如何理解“f = ap min”的类型推断?

时间:2015-03-20 17:35:15

标签: haskell type-inference

我一直在努力理解下面关于类型推断的另一个例子,

min :: Ord a => a -> a -> a
ap  :: Monad m => m (a -> b) -> m a -> m b

f   :: Ord a => (a -> a) -> a -> a
f   =  ap min

f reverse "on" -- "no"

f应用于ap时,min的类型如何推断?我应该在哪里寻找关于Haskell中类型推断主题的一些实际参考?

2 个答案:

答案 0 :(得分:3)

ap     :: Monad m => m (a -> b) -> m a -> m b
min    :: Ord a => a -> a -> a
-------------------------------------------------
ap min :: ?

由于minap的参数,这意味着我们需要找到unify这两种类型的方法:

Monad m => m (a -> b)
Ord a => a -> a -> a

要做到这一点,首先我们需要弄清楚Monad实例(如果有)适用于此处。由于a -> a -> aa -> (a -> a)相同,因此m类型变量需要等同于(->) a。 (请注意,Haskell也支持类型系统中的currying和section;就像(+) 1是函数(+)部分应用于参数1一样,(->) a是将类型构造函数(->)部分应用于类型a。)

所以我们改写为:

Monad m => m        (a -> b)
  Ord a => ((->) a) (a -> a)

这样可以很容易地看到我们需要在ap类型中进行的替换:

m := Ord a => (->) a
a := Ord a => a
b := Ord a => a

但在我们继续之前,我们需要确定Monad是否存在(->) a实例,否则这是一个类型错误。但以下是标准Monad实例之一,它将执行:

instance Monad ((->) r) where
    return a = const a
    fa >>= g = \r -> g (fa r) r

现在让我们进行替换:

ap     :: Ord a => ((->) a) (a -> a) -> ((->) a) a -> ((->) a) a
min    :: Ord a => a -> a -> a
--------------------------------------------------------
ap min :: ?

取消ap中的类型:

ap     :: Ord a => (a -> a -> a) -> (a -> a) -> a -> a
min    :: Ord a => a -> a -> a
--------------------------------------------------------
ap min :: ?

现在很容易看到解决方案:

ap     :: Ord a => (a -> a -> a) -> (a -> a) -> a -> a
min    :: Ord a =>  a -> a -> a
--------------------------------------------------------
ap min :: Ord a => (a -> a) -> a -> a

答案 1 :(得分:2)

你的问题与统一的概念有关,统一的概念可以粗略地描述为找到受环境强加的约束的表达式类型的过程。 看看Stephen Diehl开发的这个优秀的课程/手册,

  

http://dev.stephendiehl.com/fun/#january

第5章到第8章描述了你要找的东西。

相关问题