Haskell 功能o1。。尽管尽了最大努力,o3从未打过电话 主模块(Main),其中 导入文本.Printf 数据RxEvent a= 价值a |错误字符串 |完成 推导(显示,等式) 通知::(Monad m,可折叠的t,Num a1)=>t(RxEvent a->t1)->RxEvent a->m a1 通知潜艇ev= 返回$Prelude.foldl(\cs->seq(s ev)(c+1))0个子 o名称ev=do putStrLn名称 印刷电动汽车 返回0 o1=o“o1:” o2=o“o2: o3=o“o3: main=do nNotified
Haskell 功能o1。。尽管尽了最大努力,o3从未打过电话 主模块(Main),其中 导入文本.Printf 数据RxEvent a= 价值a |错误字符串 |完成 推导(显示,等式) 通知::(Monad m,可折叠的t,Num a1)=>t(RxEvent a->t1)->RxEvent a->m a1 通知潜艇ev= 返回$Prelude.foldl(\cs->seq(s ev)(c+1))0个子 o名称ev=do putStrLn名称 印刷电动汽车 返回0 o1=o“o1:” o2=o“o2: o3=o“o3: main=do nNotified,haskell,Haskell,seq确保对IO操作进行评估,但不执行。比如说 module Main(main) where import Text.Printf data RxEvent a = Value a | Error String | Done deriving (Show,Eq) notify :: (Monad m, Foldable t, Num a1) => t (RxEvent a -> t1) -> RxEvent a -> m a1 n
seq
确保对IO
操作进行评估,但不执行。比如说
module Main(main) where
import Text.Printf
data RxEvent a =
Value a
| Error String
| Done
deriving (Show,Eq)
notify :: (Monad m, Foldable t, Num a1) => t (RxEvent a -> t1) -> RxEvent a -> m a1
notify subs ev =
return $ Prelude.foldl (\ c s -> seq (s ev) (c+1) ) 0 subs
o name ev = do
putStrLn name
print ev
return 0
o1 = o "o1:"
o2 = o "o2:"
o3 = o "o3:"
main = do
nNotified <- notify [o1,o2,o3] (Value 42) :: IO Int
printf "%d subscribers notified\n" nNotified
return ()
打印“12”,而不是“45 12”。对print 45
部件进行评估,以生成IO()
值,但该值永远不会执行
要运行IO操作,必须直接或间接地使用
>=
。我知道目标函数的调用应该在一元上下文中。因此,记住那些有着神秘意义的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。一个我没有引用的包
感谢对我的问题的评论,我的代码片段的工作版本如下所示:
print (seq (print 45) 12)
你能展示一下foldl调用的lambda内部的情况吗?试试notify subs ev=do{forM\usubs$\s->s ev;return(length subs)}
@melpomene Not compileding,不幸的是:Main.hs:14:41:错误:*无法将预期的类型“m b0”与实际类型“t1”匹配。“t1”是一个刚性类型变量,由以下类型签名绑定:notify::forall(m::*->*)(t::*->*)a1 a t1。(单子m,可折叠的t,Num a1)=>t(RxEvent a->t1)->RxEvent a->Main的m a1。hs:13:11代码>发布问题4小时后,仍然只有否决票和解释性答案,但没有解决方案。我认为这对于有经验的haskell用户来说是一个简单的问题。因此,我不明白,为什么没有人怜悯我,帮助我解决这个问题。我的问题里有没有神秘的精灵?一些让它变得如此困难的含义?如果您删除类型签名,我的代码就可以工作。或者,如果您想继续使用fold:notify subs ev=foldM(\cs->s ev>>return(c+1))0 subs
foldM
不是魔术:我认为在控件中。Monad
它是作为一个递归函数实现的,但是你也可以用foldr
实现它(foldl
也可以工作,但不适用于无限列表),具体来说:foldM f b l=foldr(\a n o->f a>=n)return l b
工作正常
module Main(main) where
import Text.Printf
import Control.Monad
data RxEvent a =
Value a
| Error String
| Done
deriving (Show,Eq)
notify :: (Foldable t, Num b, Monad m) => t (RxEvent t1 -> m a) -> RxEvent t1 -> m b
notify subs ev = foldM (\ c s -> s ev >> return (c+1)) 0 subs
o name ev = do
putStrLn name
print ev
return 0
o1 = o "o1:"
o2 = o "o2:"
o3 = o "o3:"
main = do
nNotified <- notify [o1,o2,o3] (Value 42) :: IO Int
printf "%d subscribers notified\n" nNotified
return ()
o1:
Value 42
o2:
Value 42
o3:
Value 42
3 subscribers notified