从我的问题的具体实例开始,我们都知道(并且喜欢)Monad类型类:
class ... => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> mb
...
Run Code Online (Sandbox Code Playgroud)
考虑以下可能的实例,我们修改标准列表/"非确定性"实例nub,只保留每个"结果"的一个副本:
type DistinctList a = DL { dL :: [a] }
instance Monad DistinctList where
return = DL . return
x >>= f = DL . nub $ (dL x) >>= (dL . f)
Run Code Online (Sandbox Code Playgroud)
你发现错误了吗?问题是,nub :: Eq a => [a] -> [a]所以x >>= f只在条件下定义f :: Eq …
s我正在考虑在字符处分割字符串的问题c。
这表示为
break (c ==) s
Run Code Online (Sandbox Code Playgroud)
其中 Haskell 库的定义break (c ==)足够接近
br [] = ([],[])
br s@(h:t) = if (c == h)
then ([],s)
else let (h',t') = br t in (h:h',t')
Run Code Online (Sandbox Code Playgroud)
(假设我立即想要访问返回值的第二项,以便强制执行任何惰性求值。) 的递归调用似乎存储br t在h调用堆栈上,但该算法的一般意义表明:这应该是没有必要的。这是在常量堆栈空间中使用具有可变性的伪代码语言执行此操作的一种方法,其中 & 表示通过引用进行传递,列表以 LISPy 对的形式实现:
br(c,s) =
allocate res_head,res_rest
iter(c,s,&res_head,&res_rest)
return (res_head,res_rest)
iter(c,s,&res_head,&res_rest) =
case s of
[] -> set res_head = res_rest = [] -- and terminate
c:ss -> set res_head = [], res_rest = s …Run Code Online (Sandbox Code Playgroud)