这个haskell片段是如何工作的?声明/定义不匹配

时间:2016-02-18 10:56:01

标签: haskell types type-inference

糟糕的头衔,但这是我能想到的最好的!代码:

addInst                        :: [Pred] -> Pred -> EnvTransformer
addInst ps p@(IsIn i _) ce
 | not (defined (classes ce i)) = fail "no class for instance"
 | any (overlap p) qs           = fail "overlapping instance"
 | otherwise                    = return (modify ce i c)
   where its = insts ce i
         qs  = [ q | (_ :=> q) <- its ]
         c   = (super ce i, (ps:=>p) : its)

这来自文章Typing Haskell in Haskell(页面15的顶部),它解释了HUGS用于类型检查Haskell 98的算法.Pred定义如下:

data Pred   = IsIn Id Type
              deriving Eq
在addInst定义中的

,从我可以确定的,ps是谓词列表,p是谓词,i是p中的Id字段; addInst返回一个EnvTransformer。

然而 - 在这里我迷路了 - 尾随的ce似乎是第三个参数(通过命名判断的类环境,这里没有包含定义),即使签名只包含2个运算符。

我确信我在这里错过了一些东西。这是源材料中的某种错误,还是有一些Haskell魔法在这里工作?

解决方案

sepp2k指出了我正确的方向(我实际上误读了EnvTransformer的声明)。两个签名:

f :: Int -> Int -> Int -> Int
g :: Int -> (Int -> (Int -> Int))

是完全相同的,因为......好吧......无论如何,如果最后一个参数是EnvTransformer:

f :: Int -> Int -> Int -> EnvTransformer
g :: Int -> (Int -> (Int -> EnvTransformer))
h :: Int -> (Int -> (Int -> (ClassEnv -> Maybe ClassEnv)))
j :: Int -> Int -> Int -> ClassEnv -> Maybe ClassEnv

...所有这些函数都有4个参数。这就是sepp2k编写的内容,只是使用括号来强调如何在代码片段中发挥作用以及如何进行类型扩展。

1 个答案:

答案 0 :(得分:2)

EnvTransformer的定义是:

type EnvTransformer = ClassEnv → Maybe ClassEnv

如果我们在addInst的签名中扩展它,我们得到:

addInst                        :: [Pred] -> Pred -> ClassEnv -> Maybe ClassEnv

这样的功能实际上可以接受三个论点。