abe*_*sto 33 monads haskell idiomatic
我正在学习monad,这是我的第一个工作(除了琐碎的monad).随意批评其中的一切无情.我对"更惯用"和"更优雅"的回应特别感兴趣.
该monad计算执行的绑定数.
data C a = C {value :: a, count :: Int} deriving (Show)
instance Monad C where
(>>=) (C x c) f = C (value $ f x) (c + 1)
return x = C x 0
add :: (Num a) => a -> a -> C a
add x y = return $ x + y
-- Simpler way to do this? foldM is obviously something different.
mysum [x] = return x
mysum (x:xs) = mysum xs >>= add x
Run Code Online (Sandbox Code Playgroud)
luq*_*qui 94
在风格上这是非常好的.在现实世界中,我希望这种符号有60%的可能性而不是你给出的那种:
C x c >>= f = C (value $ f x) (c + 1)
Run Code Online (Sandbox Code Playgroud)
但这太小了,几乎不值得一提.
更严肃的说,不是风格而是语义:这不是一个单子.事实上,它违反了所有三个monad法律.
(1) return x >>= f = f x
(2) m >>= return = m
(3) m >>= (f >=> g) = (m >>= f) >>= g
Run Code Online (Sandbox Code Playgroud)
(如果(>=>)被定义为f >=> g = \x -> f x >>= g.如果(>>=)被认为是"应用程序"操作符,则(>=>)是相应的组合运算符.我喜欢使用此运算符来陈述第三定律,因为它表示第三定律的含义:关联性.)
通过这些计算:
(1):
return 0 >>= return
= C 0 0 >>= return
= C (value $ return 0) 1
= C 0 1
Not equal to return 0 = C 0 0
Run Code Online (Sandbox Code Playgroud)
(2):
C 0 0 >>= return
= C (value $ return 0) 1
= C 0 1
Not equal to C 0 0
Run Code Online (Sandbox Code Playgroud)
(3)
C 0 0 >>= (return >=> return)
= C (value $ (return >=> return) 0) 1
= C (value $ return 0 >>= return) 1
= C (value $ C 0 1) 1
= C 0 1
Is not equal to:
(C 0 0 >>= return) >>= return
= C (value $ return 0) 1 >>= return
= C 0 1 >>= return
= C (value $ return 0) 2
= C 0 2
Run Code Online (Sandbox Code Playgroud)
这不仅仅是您实现中的错误 - 没有"计算绑定数量"的monad.它必须违反法律(1)和(2).但是,您的违反法律(3)的事实是一个实施错误.
麻烦的是,f在(>>=)might 的定义中返回一个具有多个绑定的动作,而你却忽略了这一点.您需要添加左右参数的绑定数量:
C x c >>= f = C y (c+c'+1)
where
C y c' = f x
Run Code Online (Sandbox Code Playgroud)
这将正确计算绑定数量,并将满足第三定律,即相关性定律.它不会满足其他两个.但是,如果你+1从这个定义中删除,那么你会获得一个真正的monad,这相当于monoid 上的Writermonad +.这基本上将所有子计算的结果加在一起.您可以使用它来计算某些事物的数量,而不是绑定 - 绑定太特殊而无法计算.但是,例如:
tick :: C ()
tick = C () 1
Run Code Online (Sandbox Code Playgroud)
然后C将tick计算计算中发生的s 数.
实际上,您可以Int使用任何类型和(+)任何关联运算符替换并获取monad.这就是Writermonad的一般情况.如果操作员不是关联的,那么这将违反第三定律(你能明白为什么吗?).
| 归档时间: |
|
| 查看次数: |
1544 次 |
| 最近记录: |