【发布时间】:2016-02-12 23:02:14
【问题描述】:
我正在尝试设计嵌入式语言,其中操作可以根据值引发某些标志。我预见到对标量值和向量(例如映射、折叠等)的操作。我的想法是使用 Writer Monad 来跟踪标志。简化示例,其中实际类型为“Int”,如果任何参数为 0,则引发标志。
import Control.Monad.Identity
import Control.Monad.Writer
import Data.Monoid
type WInt = Writer Any Int
bplus :: Int -> Int -> WInt
bplus a b =
do
tell (Any (a == 0 || b == 0)) ;
return (a+b)
wbplus :: WInt -> WInt -> WInt
wbplus wa wb =
do
a <- wa ;
b <- wb ;
tell (Any (a == 0 || b == 0)) ;
return (a+b)
ex0 = runWriter (bplus 1 2)
ex1 = runWriter (bplus 0 2)
ex2 = runWriter (wbplus (return 1) (return 2))
ex3 = runWriter (wbplus (return 0) (return 2))
ex4 = runWriter (wbplus (wbplus (return 1) (return 2)) (return 2))
ex5 = runWriter (wbplus (wbplus (return 0) (return 2)) (return 2))
ex6 = runWriter (wbplus (wbplus (return 1) (return 2)) (return 0))
我不太确定实现这一点的最佳方法是什么。一些问题:
我应该像为
bplus或wbplus那样定义所有操作吗?看起来,Latters 让作曲变得更容易了。但是要使用foldM二元运算符,应该具有Int -> Int -> WInt类型。什么是列表的合适类型:
Writer Any [Int]或[Wint]?
感谢任何建议或想法。
【问题讨论】:
-
我认为你在问什么有点不清楚。 “我不太确定实现这一点的最佳方式是什么。” - 当前的实施有什么问题?如果您解释当前实现的哪些部分不令人满意,那么问题就会变得更加清晰。如果解决方案完全令人满意,那么我无法想象甚至会有一个问题......
-
我已经澄清了我的一些问题。
-
我会使用
wbplus公式——它自然更适合,因为+在道德上是一个二元运算符。你不需要使用foldM-foldr wbplus :: WInt -> [WInt] -> WInt。您可能会将列表“表示”为[WInt],因为您可以将其转换为Writer Any [Int],但不能反过来(sequence :: [Writer Any Int] -> Writer Any [Int])
标签: haskell monads writer-monad