2013-07-22 54 views
4

我的问题是关于如何使用Haskell类型签名进行分析。为了使具体的,我在看“修复”功能:简化Haskell类型签名

fix :: (a -> a) -> a 

和我写做皮亚诺十岁上下又多了一点虚构的功能:

add = \rec a b -> if a == 0 then b else rec (a-1) (b+1) 

当我检查类型,我得到我预期的类型fix add

fix add :: Integer -> Integer -> Integer 

而且它似乎工作像我期望:

> (fix add) 1 1 
2 

如何使用fixadd的类型签名来显示fix add具有上述签名?什么是“代数”,如果这甚至是合适的词,使用类型签名的规则?我怎样才能“展示我的作品”?

回答

8

ghci告诉我们

add :: Num a => (a -> a -> a) -> a -> a -> a

模某些类型类的噪音,因为第二个参数add需要一个Eq实例(你检查它与0平等)

在申请fixaddfix的签名变为

fix :: ((a -> a -> a) -> (a -> a -> a)) -> (a -> a -> a)

记住,a S IN fix :: (a -> a) -> a可以有任何类型。在这种情况下,他们有型(a -> a -> a)

因此fix add :: Num a => a -> a -> a,而这正是添加两个a正处于成长的类型。

你可以用非常代数的方式使用Haskell的类型签名,变量替换就像你期望的那样工作。事实上,类型和代数之间的直接关系为translation

+0

谢谢!我已经制定了很多(即'fix'中的'a'必须是'(a - > a - > a)')。但是,还没有一个步骤仍然存在?在((a - > a - > a) - >(a - > a - > a)) - >(a - > a - > a)和a - > a - > a' ? – Chris

+0

是的,你部分地将'fix'应用于'add'。由此产生的部分应用函数的类型为'a - > a - > a' – cdk

+3

@ twopoint718将'fix'应用于'add'会删除'((a→a→a)→a→a→a ))来自'fix'类型的参数。 –