Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 仅使用函子而非单子的严格fmap_Haskell_Monads_Strictness - Fatal编程技术网

Haskell 仅使用函子而非单子的严格fmap

Haskell 仅使用函子而非单子的严格fmap,haskell,monads,strictness,Haskell,Monads,Strictness,最近我注意到了一个对懒惰IO的恼怒 import System.IO import Control.Applicative main = withFile "test.txt" ReadMode getLines >>= mapM_ putStrLn where getLines h = lines <$> hGetContents h 用替换确实可以缓解问题。然而,我并不满意有一个Monad约束,感觉太紧了;它的同伴只需要Functor 有没有一种方法可以在没有

最近我注意到了一个对懒惰IO的恼怒

import System.IO
import Control.Applicative

main = withFile "test.txt" ReadMode getLines >>= mapM_ putStrLn
  where getLines h = lines <$> hGetContents h
替换
确实可以缓解问题。然而,我并不满意
有一个
Monad
约束,感觉太紧了;它的同伴
只需要
Functor

有没有一种方法可以在没有
单子约束的情况下编写
?若否,原因为何?我已经尝试过在所有地方施加严格的限制,但没有任何效果(以下代码不能按预期工作):

forceF::函子f=>fa->fa
forceF m=fmap(\x->seq x x)$!M
()::函子f=>(a->b)->f a->f b
f m=fmap(f$!)$!(力$!m)

我认为这是不可能的,而且一元
forceM
也不适用于所有的单子:

module Force where

import Control.Monad.State.Lazy

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)

test :: Int
test = evalState (const 1 <$!> undefined) True

forceM
需要足够严格的
(>>=)
来实际强制其参数的结果<代码>函子
甚至没有
(>>=)
。我不知道怎样才能写出一个有效的
forceF
。(当然,这并不能证明这是不可能的。)

“(\x->seq x x x)”正是
id
,所以这没有帮助。对我来说,这似乎是一个非常奇怪的定义。我会用“fm=forceM(liftM-fm)”来代替。这也解决了您的问题,在其他情况下似乎更明智。不过,我怀疑你不能为函子定义这个。
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)
module Force where

import Control.Monad.State.Lazy

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)

test :: Int
test = evalState (const 1 <$!> undefined) True
Prelude Force> test
1