xor = (/=) :: Bool -> Bool -> Bool
Хаскель тут при том, что я про него гуглил, когда это узнал.
Сегодня ночью ожидается двухгодичный даунтайм на переписывание бнвачика на Хаскель с целью перехода на identicon.
Нет, правда, поглядите, красивые пикчи же: https://mrkkrp.github.io/img/identicon-07.png https://mrkkrp.github.io/img/identicon-08.png https://mrkkrp.github.io/img/identicon-09.png https://mrkkrp.github.io/img/identicon-10.png https://mrkkrp.github.io/img/identicon-11.png https://mrkkrp.github.io/img/identicon-12.png
Пост про это дело в блоге автора.
Вы всё ещё не слушаете http://bananasandlenses.net/ ? Вот лалки. // Серьёзно, отличный подкаст, рекомендую.
Пишу опердень на attoparsec. Т.к. парсер у нас одновременно и лексер, и собственно парсер, логику приходится перемежать обработкой пробельных символов:
pVarDecl :: Parser VariableDeclaration
pVarDecl = do
string "var"
skipWhitespace1 -- пропускаем 1 или больше пробельных символов
name <- pVarName
skipWhitespace -- пропускаем 0 или больше пробельных символов
value <- optional $ do
string "="
skipWhitespace
pExpression
skipWhitespace
string ";"
return $ VariableDeclaration name value
Это утомляет. Появляется закономерное желание «переопределить точку с запятой» и явно указывать только места, где пробельные символы обязательны:
pVarDecl :: Parser VariableDeclaration
pVarDecl = do
string "var"
requiredWhitespace
name <- pVarName
value <- optional $ do
string "="
pExpression
string ";"
return $ VariableDeclaration name value
(и потом ещё для полного счастья keyword k = string k >> requiredWhitespace
, да).
Удивительно, но сам attoparsec, похоже, ничего для этого не предлагает. Итак, какие у меня варианты?
Можно определить свою монаду. Это, конечно, круто, но придётся лифтить часть Data.Attoparsec. В принципе, это всё же лучше, чем ещё двести раз набрать «skipWhitespace», но все равно грязновато.
Есть ощущение, что можно обернуть парсер в трансформер, для которого определить инстанс Monad, и будет мне счастье. Но я трансформерами никогда не пользовался даже, не говоря уж о написании собственных; возможно, это бред, а не идея.
Есть у вас какие-то соображения на этот счёт?
Появился гайд по перекатыванию с cabal-install на stack. Всем апгрейд, посоны!
https://hackage.haskell.org/package/acme-lookofdisapproval-0.1/docs/Acme-LookOfDisapproval.html
Типа, джва года ждал эту фичу и всё такое. Вот теперь-то хипсторы точно перейдут на Haskell!
Испытал экстаз от того, как красиво и элегантно в persistent пишется функция, которая инсертит запись в таблицу, если там такой ещё нет, и возвращает id записи (либо новой, либо найденной):
insertLanguage language = do
let lang = Language language
entity <- getByValue lang
case entity of
Nothing -> do insert lang
Just e -> return $ entityKey e
Пять строк, пять строк! И не какого-то там мозговыносящего матана с функторами, а нечто такое, что питонист, взглянувший на это, просто подумает: «о, в третий питон ещё и стрелочки какие-то впилили, прикольно».
Тот факт, что insert
возвращает id созданной записи, ранее было поводом отдельного экстаза.
У Ромы Чепляки неизменно отличные презентации: http://ro-che.info/docs/2013-11-14-haskell-and-oop.html
Победил HXT, вынув из XML'ек условия задач для рассчётки. Всё ещё не понимаю, как может стрелка иметь тип ArrowXml a => a XmlTree XmlTree и при этом возвращать не одно значние, а несколько. Не понимаю, как это всё разветвляется и сливается обратно без необходимости делать map и concat. Аргх.
--Minoru, который думал, что он понял стрелки
А поясните мне за песочницы: разве они не должны наследовать пакеты, установленные в системе и у пользователя?
Я почему спрашиваю: pandoc-1.9.4.5 не собирается в sandbox (похоже, там кто-то захардкодил пути и sh не может найти какой-то файл), так что я поставил его под юзером (то есть в ~/.cabal). Но после того, как я делаю cabal sandbox init, cabal list pandoc утверждает, что установленных версий pandoc нет. Я что-то делаю не так, или я чего-то не так понял?
ghc doesn't fuse lists (avoiding success at all costs?)