在"数据类型单点"中,Swierstra写出给定的Free(他称之为Term)并且Zero您可以实现Identity monad:
data Term f a = Pure a
| Impure (f (Term f a))
data Zero a
Run Code Online (Sandbox Code Playgroud)
Term Zero现在是身份monad.我明白为什么会这样.问题在于,Term Zero由于令人讨厌的Functor f =>约束,我永远不能用作Monad :
instance Functor f => Monad (Term f) where
return x = Pure x
(Pure x) >>= f = f x
(Impure f) >>= t = Impure (fmap (>>=f) t)
Run Code Online (Sandbox Code Playgroud)
如何制作ZeroFunctor?
instance Functor Zero where
fmap f z = ???
Run Code Online (Sandbox Code Playgroud)
好像有一个窍门在这里:由于Zero没有构造,Impure …
我是Scala的新手,并一直在尝试使用其出色的组合解析器库.我一直在尝试编译这段代码:
import scala.util.parsing.combinator._
...
val r:Parsers#ParseResult[Node] = parser.parseAll(parser.suite,reader)
r match {
case Success(r, n) => println(r)
case Failure(msg, n) => println(msg)
case Error(msg, n) => println(msg)
}
...
Run Code Online (Sandbox Code Playgroud)
但我不断收到这些错误:
TowelParser.scala:97: error: not found: value Success
case Success(r, n) => println(r)
^
TowelParser.scala:98: error: not found: value Failure
case Failure(msg, n) => println(msg)
TowelParser.scala:99: error: object Error is not a case class constructor, nor does it have an unapply/unapplySeq method
case Error(msg, n) => println(msg)
Run Code Online (Sandbox Code Playgroud)
我尝试了很多不同的东西,比如:
case Parsers#Success(r, n) => println(r) …Run Code Online (Sandbox Code Playgroud) 据我所知,Haskell的ST monad是独一无二的,它允许我描述一个本地使用可变内存的计算,但仍然提供一个纯粹的接口.也就是说,它允许我改变内存,只要该突变不会逃避计算.最简单的例子就是:
runST $ newSTRef "trying to return a memory reference."
Run Code Online (Sandbox Code Playgroud)
这导致编译时错误(多酷!):
Couldn't match type ‘a’ with ‘STRef s a0’
because type variable ‘s’ would escape its scope
This (rigid, skolem) type variable is bound by
a type expected by the context: ST s a
at <interactive>:1:1-18
Expected type: ST s a
Actual type: ST s (STRef s a0)
In the second argument of ‘($)’, namely ‘newSTRef 0’
In the expression: runST $ newSTRef 0
Run Code Online (Sandbox Code Playgroud)
我的理解是,如果允许可变引用逃脱计算,它可以在其他地方进行变异,并且我的ST计算可能不再具有纯接口(它可能在不同的调用上返回不同的值).
我的问题是:这是如何实施的?我看到runST和newSTRef的定义大量使用了RankNTypes,但是我无法理解这些类型如何产生上面的编译错误.
我正在完成“Beginning Haskell”一书中的练习。练习 4-8 将二叉搜索树作为 Functor 的实例并定义 fmap。这就是树的样子:
data BinaryTree a = Node a (BinaryTree a) (BinaryTree a)
| Leaf
deriving Show
Run Code Online (Sandbox Code Playgroud)
因为它是一棵搜索树,所以对树的所有操作都必须保持左子树中的所有值<节点的值,右子树中的所有值>节点的值的不变性。这意味着树中的所有值都必须是有序的 ( Ord a => BinaryTree a)。
两个问题:
fmap :: (a -> b) -> BinaryTree a -> BinaryTree b,我如何强制执行这b也是序数?如果它不必是 Functor,我可以简单地做fmapOrd :: (Ord a, Ord b) => (a -> b) -> BinaryTree a -> BinaryTree b,但 Functor 类型类不强制执行 Ord 约束。