to post messages and comments.

ucnv_getMaxCharSize strikes back.

Ставлю text-icu на Windows:
```
stack exec — pacman -Sy mingw64/mingw-w64-x86_64-icu
stack build text-icu
```

После этого, при попытке его использовать:
```
Prelude> import Data.Text.ICU
Prelude Data.Text.ICU> :t Root
Root :: LocaleName
Prelude Data.Text.ICU> Root
ghc.EXE: addDLL: icudt (Win32 error 126): The specified module could not be found.
```

Ок. Нашёл, где лежат dll-ки, положил копии с нужными именами (icudt58.dll -> icudt.dll).
(На всякий случай: инфа о пакетах в <stack_root>\snapshots\<...>\pkgdb\*.conf)
Теперь такая ошибка:
```
Prelude> import Data.Text.ICU
Prelude Data.Text.ICU> Root
ghc.EXE: C:\stack_root\snapshots\61ba18c6\lib\x86_64-windows-ghc-8.0.1\text-icu-0.7.0.1-3ZPlchKHjedDm1t6cAa5us\HStext-icu-0.7.0.1-3ZPlchKHjedDm1t6cAa5us.o: unknown symbol `ucnv_getMaxCharSize_58'

ghc.EXE: unable to load package `text-icu-0.7.0.1'
```

Погуглил. Есть пара похожих случаев. То ли версии icu 57, 58 проблемные, то ли либа text-icu что-то не учитывает.
github.com
Ещё вспомнил про #2885797 .

В итоге скачал icu версии 59, удалил text-icu, переустановил text-icu с указанием путей до этой версии.
```
stack exec — ghc-pkg unregister --force text-icu
stack install text-icu --extra-lib-dirs=C:\...\icu59\bin64 --extra-include-dirs=C:\...\icu59\include
```
Заработало.

Меняем Network.URI на URI.ByteString, regex-tdfa на regex-pcre и получаем ускорение разбора урлов на порядок, с 10 тысяч в секунду до ста тысяч. Хотя сишечке все равно проигрывает в два-три раза, но это уже нормально.

Положим у меня есть тип data T f = T (forall a. f a -> a) и линза вида Lens (f x) (f x) x x, где f — полиморфный контейнер фиксированного размера. Могу я как-нибудь при помощи второго наполнить первое?

А давайте спецолимпиадку по типам? Есть код codegists.com это Freer для стрелок, но с ним проблема, нужно квадратичное число инстансов, так надо определять Category (Freer Category eff), Category (Freer Arrow eff), несмотря на то, что Category => Arrow. Что очевидно очень печально, и хотелось бы это поправить.

У меня получилось такое:

gist.github.com

Есть чуть более простые варианты но с тоже с квадратичным числом инстансов, хоть и более простых. Так же можно запилить вариант на TH который будет сразу генерить полный instance search, но это читерство.

Принимаются варианты и предложения по улучшению гиста.

Идиота вопрос. Ниже "псевдокод", который естественно не тайпчекается. Вопрос, как изобразить "нечто аналогичное", что-то вроде isInstanceOf?

```
newtype Name = Name { getName :: Name }
newtype Phone = Phone { getPhone :: Int }

data Selection = Selection Int Int

data PhoneContact = PhoneContact Name Phone
data PhoneWithSelectionContact = PhoneWithSelectionContact Name Phone Selection

class IsContact a

instance IsContact PhoneContact
instance IsContact PhoneWithSelectionContact

filterSelections :: IsContact a => [a] -> [PhoneWithSelectionContact]
filterSelections xs = filter isSelection xs
where
isSelection :: IsContact a => a -> Bool
isSelection PhoneContact = False
isSelection PhoneWithSelectionContact = True
```

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

Добавил haskell, т.к. столкнулся с тем, что в пакете HDBC-odbc по умолчанию модуль пытается считать DSN из C:\Windows\System32\odbcad32.exe, а не C:\Windows\SysWoW64\odbcad32.exe. Сил никаких нет, хочу заполучить данные из MS Access, попутно простреливая себе колени. Есть идеи, куда нажать?

Курс Functional Programming In Haskell (University Of Glasgow) на FutureLearn на поверку оказался вообще ни о чём. Черновик курса, набор недописанных плохо упорядоченных материалов. Лекторы неинтересные.

hPutStr :: Handle -> BL.ByteString -> IO ()
hPutStr hdl lbs = wantWritableHandle "Data.ByteString.Lazy.hPutStr" hdl $ \hdl__ ->
  BL.foldrChunks (go hdl__) (commit hdl__) lbs
 where
  go hdl__ (S.PS ps s l) rest = do
   unless (l == 0) $ withForeignPtr ps $ \p -> do
    _ <- bufWrite hdl__ (p `plusPtr` s) l True
    pure ()
   rest
  commit hdl__ =
   case haBufferMode hdl__ of
    BlockBuffering _   -> do return ()
    _line_or_no_buffering -> do flushWriteBuffer hdl__
                  return ()

В догонку к #2877381. Теперь я не только не понимаю зачем линзы (на самом деле призмы) обмазаны Profunctor, но ещё и не понимаю зачем нужен Profunctor, если есть Arrow. Стрелки в принципе делают всё то же самое.

amap :: (Category p, Strong p, Choice p, Profunctor p) => p a b -> p [a] [b]
amap = make . it . tasty where -- (p ||| amap p) where
  -- make :: Profunctor p => p (Either () (a,[a])) (Either () (b,[b])) -> p [a] [b]
  make = dimap view build
    where
     build = either (const []) (uncurry (:))
     view = maybe (Left ()) Right . uncons
  -- it :: (Choice p, Profunctor p) => p (a,[a]) (b,[b]) -> p (Either () (a,[a])) (Either () (b,[b]))
  it = right'
  -- tasty :: (Choice p, Category p, Strong p) => p a b -> p (a,[a]) (b,[b])
  tasty p = p ||| amap p
  (|||) x y = first' x >>> second' y

меняем it на right' и все перестает компилироваться, почему?

Каждый раз хочу оператор для \meval err -> maybe (Left err) Right meval. Почему в куче base нет оператора для перехода от Maybe к Either? В принципе можно обмазаться error и catch, но получится говно.

neilmitchell.blogspot.ru — Вот тут Mitchell'у пишут, что static pointer'ы не стабильны и могут меняться от сборки к сборке, что довольно сильно ограничивает применимость его идеи. Это меня в принципе не удивило, но потом я вспомнил, что static pointers extension рожали в муках для нужд cloud haskell с целью гонять по сети указатели на функцию. Так вот вопрос: как им там живётся с такими гарантиями стабильности?

Prelude> let x = (id True, id undefined)
Prelude> :sprint x
x = _
Prelude> let x = (True, id undefined)
Prelude> :sprint x
x = _
Prelude> let x = (True, undefined)
Prelude> :sprint x
x = (,) True _
Prelude> let x = (True, undefined::Int)
Prelude> :sprint x
x = (True,_)
Prelude> let x = (True, False)
Prelude> :sprint x
x = (True,False)

кто-нить может мне объяснить почему вывод именно такой?

Хочу плагин к GHC, который вычисляет какие исключения может бросать функция. Причем, какой-нить тупой, ей даешь на вход текстовый файлик со списком:

Module.function : Module.Exception

он используя эту информацию собирает код и генерит на выходе файлик дополненый всеми собранными функциями, это же реально?

haskell не для продакшена и нигде не используется.

Тем не менее вчера встретил знакомого, который недавно подался в программисты, работает в какой-то фирме, которые делают что-то с магистральными каналами и всякий софт для этого. Так вот, он там похвастался, что у него есть знакомый живой хацкелист, на что ему сказали, тащи его сюда, у нас тут есть пачка кода написанного ещё давно, который работает, но никто не понимает как, пусть объяснит.

Вот так неожиданно haskell оказывается в продакшенах, посмотрю код потом, может подробности расскажу.

давно не было haskell тут:

MAIN = go (replicate 100000000 1)
where
go [] = return ()
go xs0 =
let ~(xs, ys) = span (>0) xs0
in do print $ foldl' (+) 0 xs
go ys

вот такая программа, если запустить её прибивает OOM Killer.
меняем $ на $! и она работает в constant space.

Просмотр stg показывает совсем мало разницы, в падающем случае unboxed tuple возвращаемый span снова боксится:

let blabla = case GHC.List.$wspan lvl1_r71d wild_s71y of _ [Occ=Dead] {
(#,#) ww1_s71D [Occ=Once] ww2_s71E [Occ=Once] ->
(,) [ww1_s71D ww2_s71E];

в обычном просто дальше идёт код.

Так же в падающем варианте идёт ещё одна аллокация:

let {
sat_s71M [Occ=Once, Dmd=<L,1*U>] :: GHC.Base.String
[LclId, Str=DmdType] =
\s srt:SRT:[r2vu :-> GHC.Show.$w$cshowsPrec3, r71e :-> go_r71e] []
case ds1_s71B of _ [Occ=Dead] {
(,) xs_s71G [Occ=Once] _ [Occ=Dead] ->
... бла-бла-бла тут развернутый fold и show

я понимаю почему падающий жрёт больше, но я не понимаю почему это не больше на какой-то множитель, почему ничего не освободжается.

<rubber-duck-mode>
А как бы задавать неявные методы для решения ОДЕ, так чтобы пользователь мог задать стратегию решения?
После размышления, у меня ощущение, что если в явном методе я могу возвращать (в простом случае без доп структуры):
phi :: x -> f x -> f x
то для неявного я должен писать:
phi :: x -> (f x, f x) -> f x

где теперь мне на вход подается начальная координата и первое приближение, и в ответ я выдаю набор следующих координат. Вроде в этом случае вся свобода, которая должна быть остается в руках у пользователя, можно и начальное приближение удобным способом выбирать, и решать хочется ли fixed point или newton iteration или вообще заанролить метод на нужную глубину.
</rubber-duck-mode>

Хочу систематизировать лапшу из команд и конфигов:
— для билда (с докером или без) и деплоя (scp/rsync)
— на локальную машину, тестовый стенд и продакшн.

Смотрю в сторону Shake. Как оно в целом? Или что другое посоветуете?

Интересный текст richardhaskell.com
коротко, хардварная имплементация раз в 10 быстрее чем реализация на ЯП, Си как обычно тормозит, FORTH-процессоры это ня, надо зопейлить таковой на своей плисине, можно попробовать уходить в крайности RISC/CISC и посмотреть что — лучше, а что — хуже.

При попытке вкатить cabal-install обнаружилась острая нехватка различных ебилдов. Пока восполнял её, обнаружил, что у echo в вебне hackage'а указаны одни констрейнты, а в тарболе с кодом — другие.