为Haskell代数数据类型Terms定义Functor实例的Abs构造子处理问题
你遇到的问题核心是Abs构造子的参数类型嵌套了两层Functor:外层是Terms,内层是Maybe,只需要把两层fmap组合就能解决。
首先明确各部分的类型对应关系:
fmap针对Terms的签名为(a -> b) -> Terms a -> Terms b- 匹配到
Abs t分支时,t的类型是Terms (Maybe a),我们需要将其转换为Terms (Maybe b)才能构造符合返回要求的Abs值 Maybe本身就是Functor实例,你手里的函数f :: a -> b可以通过fmap提升为fmap f :: Maybe a -> Maybe b,正好是转换t需要的参数函数- 把提升后的函数传给
Terms的fmap,就能完成Terms (Maybe a)到Terms (Maybe b)的转换
修改后的完整Functor实例代码如下:
instance Functor Terms where fmap f (Var x) = Var (f x) fmap f (App t1 t2) = App (fmap f t1) (fmap f t2) fmap f (Abs t) = Abs (fmap (fmap f) t) fmap _ (Const n) = Const n fmap f (Add t1 t2) = Add (fmap f t1) (fmap f t2) fmap f (IfZero t1 t2 t3) = IfZero (fmap f t1) (fmap f t2) (fmap f t3) fmap _ Y = Y
上述实现可以正常通过类型检查,逻辑上也符合lambda演算项的映射规则:Abs内部绑定的变量对应Nothing不会被fmap影响,自由变量对应Just a会正常应用f完成转换。
内容的提问来源于stack exchange,提问作者ObsidiousD
相关产品推荐
相关产品推荐

