Dlaczego w Haskell istnieją dwie różne monady typu Writer? Intuicyjnie dla mnie czytanie "ścisłej monad pisarza" oznacza, że <>
jest ścisły, więc nie ma w nim nagromadzenia thunk. Jednak patrząc na kod źródłowy, okazuje się, że nie jest to przypadek:Jaki jest sens posiadania leniwej/ścisłej wersji Writera?
-- Lazy Writer
instance (Monoid w, Monad m) => Monad (WriterT w m) where
-- ...
m >>= k = WriterT $ do
~(a, w) <- runWriterT m
~(b, w') <- runWriterT (k a)
return (b, w <> w')
W ścisłym wersji wzory nie są niepodważalne, to znaczy ~
brakuje. Tak więc powyżej powyższe jest to, że m
i k a
nie są oceniane, ale przechowywane jako thunks. W wersji ścisłej są one oceniane w celu sprawdzenia, czy pasują do wzorców krotek, wynik jest podawany do <>
. W obu przypadkach wartość >>=
nie jest obliczana, dopóki coś faktycznie nie wymaga wartości wynikowej. Tak więc rozumiem, że zarówno leniwe, jak i ścisłe wersje robią to samo, z wyjątkiem tego, że mają thunk w innym miejscu w definicji >>=
: lazy produkuje runWriterT
thunks, strict produkuje <>
thunks.
To pozostawia mnie z dwoma pytaniami:
- Czy powyższe prawo, czy mogę rozumieją ocenę tutaj?
- Czy mogę wykonać ścisłą
<>
bez pisania własnego opakowania i instancji?
Na pytanie 1 odpowiedź brzmi: http://stackoverflow.com/questions/13186512/difference-between-haskells-lazy-and-strict-monads-or-transformers –