9
一つの刺激が原因怠惰なIOに最近厳密FMAPは、怠惰なIOでないモナド
import System.IO
import Control.Applicative
main = withFile "test.txt" ReadMode getLines >>= mapM_ putStrLn
where getLines h = lines <$> hGetContents h
私の注意をキャッチし、上記のプログラムは、何も出力しません。だから私はこれがfmap
の厳密なバージョンで解決できると思いました。そして実際、私はちょうどそのようなコンビネータを思い付くんでした:
forceM :: Monad m => m a -> m a
forceM m = do v <- m; return $! v
(<$!>) :: Monad m => (a -> b) -> m a -> m b
f <$!> m = liftM f (forceM m)
が実際に問題を軽減ん<$!>
で<$>
を交換します。しかし、私は満足していません。 <$!>
にはMonad
という制約があります。同義語<$>
はFunctor
のみ必要です。
<$!>
には、Monad
の制約がありません。そうなら、どうですか?そうでない場合は、どうしてですか?私は無駄(は、必要に応じていない仕事がない、次のコード)に、あらゆる場所に厳しさを投げて試してみた:
forceF :: Functor f => f a -> f a
forceF m = fmap (\x -> seq x x) $! m
(<$!>) :: Functor f => (a -> b) -> f a -> f b
f <$!> m = fmap (f $!) $! (forceF $! m)
"(\ x - > seq x x)"は正確には "id"です。 –
これは私にとって<$!>の非常に奇妙な定義のようです。代わりに "f <$!> m = forceM(liftM f m)"としてください。これはまたあなたの問題を解決し、他の文脈ではもっと賢明なようです。私はあなたがファンクタのためにこれを定義することはできないと思う。 – lpsmith