2014-07-23 166 views
2

我正在为CIS 194的作业问题工作。
我停留在Homework 5,问题6.功能类型实例

的类型类Expr用于表示表达和用于容纳变量中的任何表达式的类型类HasVars
该问题要求对M.Map String Integer -> Maybe Integer实施Expr的实例,其中MData.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转换为上述函数。

我没有提出解决问题的其他部分,因为它可能包含破坏者。

回答

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

在这个阶段也许太先进,但如果你使用'Applicative'到'Maybe'结合s,您也可以将它用于功能部分。 'add = liftA2 $ liftA2(+)'。 –

+0

谢谢,这是有道理的。然而'lit :: Integer - > a'仍然让我失望。我需要使用一个整数来创建函数。所以我需要创建一个地图或添加到一个? –

+2

@dare_take'lit'可能会让一个表达意思是不变的,所以让它使用一个映射参数但忽略它。 –