Чтобы добавлять сообщения и комментарии, .

@kb:
kb

Пацаны, налетай (почему-то меня пригласили на интервью, но я откажусь т.к. и так работы хватает) odesk.com

@kb:
kb

i.imgur.com

Помогите с выбором (или предложите что-то попроще)

@kb:
kb

Посоветуйте, кто пользовался, хороший LRU для хаскеля (или как искать). При том, что скорее всего придётся немного допилить его API под конкретную нужду (а может взять и свой небольшой написать?).

Паттерн использования такой: идёт поток ивентов, среди них нужно учитывать только последний по какому-то id-полю. То есть пока я думал сделать LRU-кеш, переписывая по этому самому id-полю значения, при удалении из LRU считать объект "конечным", также при окончании ивентов всё, что внутри LRU считать конечным.

@kb:
kb

Лайк reddit.com

@kb:
kb

А вообще, очень рад расширению OverloadedLists [0]. Особенно в контексте удобного создания непустых списков, например.

haskell.org

@kb:
kb

Если, вдруг, кому нужно bitbucket.org

@kb:
kb

Ох, руки болят, чувство что отошлют куда подальше, но надежда пока еще не умерла github.com

@kb:
kb

Что модно использовать для непустых списков? [0], [1] или [2]?

[0]: hackage.haskell.org
[1]: hackage.haskell.org
[2]: hackage.haskell.org

@kb:
kb

Что делает fixIO? hackage.haskell.org

Пример использования есть здесь hackage.haskell.org

@kb:
kb

Палю метод улучшения вашего грепа для поиска по текстовым исходникам (кроме различных масок файлов и директорий):

M-x customize-group
grep

В поле `grep-find-command` вместо

'("find . -type f -exec grep -nH -e {} +" . 34)

Ставьте:

'("find . -type f -exec cut -c1-2000 | grep -nH -e {} +" . 34)

Таким образом каждая линия будет обрезаться до первых 2000 символов при поиске. Мне лично это как раз то, что нужно.

@kb:
kb

Этот момент, когда ненависть переростает в дружбу.

ubuntuone.com

@kb:
kb

Вопрос к читавшим Functional Data Structures Окасаки. Вы читали вникая в доказательства или нет? То есть, я сейчас прочитал до места, где сложность очередей доказали через Banker's и Physicist Method'ы, и осознал, что либо мне нужно перечитывать всё с самого начала (а перед этим желательно почитать много разных примеров попроще по доказательству при помощи амортизации), либо забить и читать доказательства поверхностно, а внимательно читать только код.

@kb:
kb

Вот, думаю начать младшего брата постепенно учить программированию. Решил начать со схемы (заодно и сам поучу), поставил Racket. Изначально думал взять SICP (который я уже прочёл и знаю, что он крут), но на сайте Racket увидел рекоммендацию взять "How to Design Programs, Second Edition". Решил пока что с неё и начать, но что-то мне подсказало, что на английском будет учить крайне сложно, и всё-таки лучше начать учить по-русски.

Собственно, вопросы:
1. что делать?
2. есть ли "How to Design Programs" на русском?
3. насколько сумасшедшей считается идея попробовать перевести эту книгу на русский постепенно?

Спасибо!

@kb:
kb

Вообще говоря, вот этот саблаймо-подобный алгоритм поиска явно как-то можно улучшить, т.к. до сих пор, ища по проекту только что, например, файл "terrain.py", оно умудряется заматчить кучу хлама, где таки находится t.*e.*r.*r.*a.*i.*n. Ну, вы поняли. Интересно на досуге подумать о хороших решениях.

@kb:
kb

Пожалуй, одной из прелестей FirefoxOS будет то, что теперь в этом
изобилии фиговых интерфейсов можно будет сесть и за один-два вечера
наотправлять "пулл-реквестов" к любимым приложениям, которые будут
банально расставлять отступы, выравнивать шрифты ну и так
далее. Почему-то на андроиде это делать, видимо, очень сложно.

@kb:
kb

Драйвер редиса возвращает `Redis (Either Reply a)`. При операции `HGET` возвращает, соответственно, `Redis (Either Reply (Maybe ByteString))`, типа значения по ключу может и не быть. Программист для упрощения пишет сначала специальную функцию `redis'`, которая заворачивает ответ редиса в EitherT-based монаду, чтоб соединять подобные вычисления и возвращать первую неудачу:

```
newtype Redis' a = Redis' (EitherT Redis.Reply Redis.Redis a) deriving (MonadIO)
instance Monad Redis' where
    return = Redis' . EitherT . return . Right
    (Redis' m) >>= f = Redis' $ m >>= \rv -> unwrapRedis' $ f rv
redis' = Redis' . EitherT
```

Таким образом, теперь, если вы получаете ответ `Redis (Either Reply a)`, вы его преобразуете в

```
Redis' (EitherT Reply Redis a)
```

и можете соединять подобные вычисления в do-блоке типа:

```
do
    res <- redis' $ Redis.hget foo bar
    res2 <- redis' $ Redis.hget baz zab
```

и вычисление остановится на первом возврате ошибки.

Далее. Программисту необходимо по кучке значений сделать `HGET` и вернуть это как-то внутри кортежа, поскольку мы внутри новой монады `Redis'` -- завернуть результат в неё. В случае, если значения хоть по одному ключу не существует, хочется вернуть `Nothing` для всех. Потому создаётся новая монада:

```
newtype HashFields a = HashFields (MaybeT Redis' a)
    deriving (Functor, Monad)
instance Applicative HashFields where
    pure = return
    (<*>) = ap
```

описывающая вычисления типа `Redis'`, которые могут вернуть неудачу. Пишется новая функция

```
hashField = HashFields . MaybeT . redis'
```

способная завернуть результат неудачи в новую монаду, которая умеет останавливаться на первой неудаче. Также пишется специальная функция для `HGET`:

```
getField :: ByteString -- ^ Key
         -> ByteString -- ^ Hash field name
         -> HashFields String
getField key field = fmap toString $ hashField $ Redis.hget key field
```

Также напишем функцию, которая "запустит" наше вычисление:

```
getRedisFields :: forall a. HashFields a -> Redis' (Maybe a)
getRedisFields (HashFields f) = runMaybeT f
```

И теперь лёгким движением руки мы можем сделать что-то вроде:

```
getRedisFields ((,,,,,) <$>
    getField k "foo" <*>
    getField k "bar" <*>
    getField k "baz" <*>
    getField k "zab" <*>
    getField k "rab" <*>
    getField k "oof")
```

Вопрос: вам не кажется это "слишком"? Я пока еще не настолько просто манипулирую типами в голове, чтоб ощутить всю ситуацию, хорошо хоть в целом могу медленно прости по шагам по коду, но есть ощущение, что что-то здесь не так.

@kb:
kb

Spiderpig, Spiderpig, does whatever Spiderpig does!
(c) Чувак, отвечающий на критику Леннарта о том, что Убунту без
Системд обречены. // да, новые разборки, новые расколы и выяснения
отношений

gentooexperimental.org

@kb:
kb

Кстати, официально признаю идею перенести Ctrl на капслок очень удачной. Действительно теперь могу сказать, что стало лучше, причем не только в емаксе, а в файрфоксах и прочих местах тоже.

@kb:
kb

Мда. Докер кеширует как-то очень странно, чего-то я не понимаю. Один и тот же кусок вместо чтения из кеша заново пересобирает иногда (но не всегда). В связи с этим придётся "коммитить образ" ghc/cabal и дальше с него начинать. В общем, штука очень крутая, но до конца не ясны все плюсы и минусы в плане полезных юз-кейсов.

@kb:
kb

screencloud.net