我正在处理CIS 194的作业问题 我被困在问题6的Homework 5。
类型类Expr
用于表示包含变量的任何表达式的表达式和类型类HasVars
。
该问题要求为Expr
实施M.Map String Integer -> Maybe Integer
的实例,其中M
为Data.Map
。
class Expr a where
add :: a -> a -> a
mul :: a -> a -> a
lit :: Integer -> a
以下是Expr
Integer
的代码。
instance Expr Integer where
add m n = m + n
mul m n = m * n
lit m = m
以及函数的HasVars
实例
instance HasVars (M.Map String Integer -> Maybe Integer) where
var s = M.lookup s
我很担心如何为函数类型创建Expr
的实例。
如何进行模式匹配或从函数中提取值?
类型为a-> a -> a
,因此我没有Map
来提取值,而var
中的ShowVars
用于将String
转换为功能。
我没有提出问题其他部分的解决方案,因为它可能包含剧透。
答案 0 :(得分:8)
好吧,首先写出签名,这样就可以清楚地知道应该是什么东西了。为了使其更具可读性,
type MS2I = M.Map String Integer
type Integer' = Maybe Integer
然后
add :: (MS2I -> Integer') -> (MS2I -> Integer') -> (MS2I -> Integer')
所以你可以从
开始add m n = o
where m, n, o :: MS2I -> Integer'
所以o
是一个拍摄地图的函数......你可以定义:
add m n = o
where o ms2i = ...
现在,你有了一张地图。您可以将其提供给参数:
add m n = o
where o ms2i = let i1 = m ms2i
i2 = n ms2i
i1, i2 :: Integer'
in ...?
其余的应该是显而易见的,你只需要将两个Maybe Integer
组合成一个新的Applicative
。 (最好使用import Control.Arrow
instance Expr (Kleisli Maybe MS2I Integer) where
add m n = arr (uncurry(+)) . (m&&&n)
。)
有趣和参考,这是一个超级精简版:
{{1}}