migmit: (Default)
[personal profile] migmit
utop[0]> open Core.Std;;
utop[1]> let a = lazy (printf "A\n"; 0);;
val a : int lazy_t = <lazy>
utop[2]> let b (a : int) = lazy (printf "B\n"; 0);;
val b : int -> int lazy_t = <fun>
utop[3]> Lazy.force Lazy.(a >>= b);;
A
B
- : int = 0

Ну ё-моё...

Date: 2013-08-13 01:25 pm (UTC)
From: [identity profile] d-ao.livejournal.com
Что-то не так?

Date: 2013-08-13 01:29 pm (UTC)
From: [identity profile] migmit.livejournal.com
Не так. Какого фига a вообще вычисляется? Оно для результата не нужно нафиг.

Date: 2013-08-13 01:54 pm (UTC)
From: [identity profile] d-ao.livejournal.com
Ленивость в хаскеле:

a = do
print "A"
return 0

b x = do
print "B"
return 0

main = a >>= b

$ ./Proba01
"A"
"B"

Date: 2013-08-13 03:49 pm (UTC)
From: [identity profile] migmit.livejournal.com
a = trace "A" 0 и далее аналогично.

Date: 2013-08-13 02:56 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
У b строгий аргумент же. Сам так описал.

Date: 2013-08-13 03:53 pm (UTC)
From: [identity profile] migmit.livejournal.com
Так вот и получается, что везде надо руками описывать, что вычислять, а что нет. Такую "ленивость" я могу руками сделать, и новое ключевое слово не понадобится, только вместо lazy x надо будет писать lazy (fun _ -> x).

Date: 2013-08-13 04:12 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Да, получается так.
Мне в окамле слово lazy за 5 лет лишь один раз пригодилось. Там, где в хаскеле используют ленивые списки, в окамле обычно хватает Enum'ов. В остальном просто стиль работы другой, энергичный. Потому особой нужды в ленивости и не чувствуется. Пытаться из окамла изобразить хаскель, делая все ленивым, - плохая затея.
Edited Date: 2013-08-13 04:12 pm (UTC)

Date: 2013-08-13 05:02 pm (UTC)
From: [identity profile] migmit.livejournal.com
Понятно, что плохая. Просто я думал, что лишний кейворд введён не просто так.

Date: 2013-08-13 05:28 pm (UTC)
From: [identity profile] nponeccop.livejournal.com
Под ленивостью call by need понимают очень редко. Такого добра, как, например, https://github.com/pkrumins/node-lazy (прекривейшей эмуляции стримов на эвент-эмиттерах) полно.

В этом плане в Википедии засилие учоных - см. http://nponeccop.livejournal.com/333219.html?thread=3079331#t3079331

Date: 2013-08-13 04:15 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
> (fun _ -> x).

Это call by name, не ленивость, тут будет многократное исполнение при многократном обращении.

Date: 2013-08-13 04:50 pm (UTC)
From: [identity profile] nponeccop.livejournal.com
lazy, в который передается наш фан, будет реализовывать однократность, всё в порядке.

А второй компонент call by need - sharing - сам окамл делает безо всяких усилий с нашей стороны.

Date: 2013-08-13 05:09 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Вот и я сперва подумал, что тут ключевое слово, и решил, что опечатка.

Date: 2013-08-13 05:22 pm (UTC)
From: [identity profile] nponeccop.livejournal.com
А причем тут ключевое слово?

Date: 2013-08-13 05:27 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Там lazy - его собственная ф-я, не окамловская родная.

Date: 2013-08-13 05:29 pm (UTC)
From: [identity profile] nponeccop.livejournal.com
Ну так его функция прекрасно сможет заимплементить санк, получив () -> a на вход.

Date: 2013-08-13 06:04 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Ага. Просто сперва не было ясно, что там именно своя реализация. Ибо не со своей и fun _ -> не надо.

Date: 2013-08-13 06:05 pm (UTC)
From: [identity profile] migmit.livejournal.com
[livejournal.com profile] thedeemon увидел слово lazy и, так как оно совпадает с имеющимся ключевым словом, решил, что я написал его там по ошибке.

Date: 2013-08-13 04:54 pm (UTC)
From: [identity profile] migmit.livejournal.com
Потому что цитировать надо полностью. У меня сейчас под рукой компилятора нет, а ssh-ить лень, но будет как-то так:
type 'a lazy_inside = Ready of 'a | Postponed of (() -> 'a)
type 'a lazy_t = 'a lazy_inside ref
lazy f = ref (Postponed f)
force r =
  match !r with
    | Ready x -> x
    | Postponed f -> let x = f () in r := Ready x; x
(>>=) r f = lazy (fun _ -> force (f (force x)))

Date: 2013-08-13 05:08 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Да, так ок.