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