use*_*769 4 haskell type-inference
我正在学习哈斯克尔.有人可以解释这两种类型是如何推断的,Num(a - > a)是什么意思?
liftM2 (==) id :: Eq a => (a -> a) -> a -> Bool
(\x->x+1) id :: Num (a -> a) => a -> a
Run Code Online (Sandbox Code Playgroud)
在第一种情况下我们有
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
(==) :: Eq a => a -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
通过设置a1=a和a2=a我们得到
liftM2 (==) :: (Eq a, Monad m) => m a -> m a -> m Bool
Run Code Online (Sandbox Code Playgroud)
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
Run Code Online (Sandbox Code Playgroud)
因此,类型的函数r -> a可以在Monad a => m a期望的位置传递.因为id :: a -> a我们得到了r=a,m a = a -> a并且m Bool = a -> Bool导致了
liftM2 (==) id :: (Eq a) => (a -> a) -> (a -> Bool)
Run Code Online (Sandbox Code Playgroud)
对于第二种类型,该类型签名所说的是函数类型有一个Num实例(a -> a).
Haskell数字文字是多态的,((\x -> x + 1) id)实际上是以下的语法糖:
((\x -> x + (fromInteger 1)) id)
Run Code Online (Sandbox Code Playgroud)
其中,通过β还原
id + (fromInteger 1)
Run Code Online (Sandbox Code Playgroud)
这假设(fromInteger 1)是一个函数,并且有一种方法可以将两个函数与+运算符一起添加.默认情况下,这是不可能的,但如果您真的想要,Haskell允许您为函数定义添加.
{-# LANGUAGE FlexibleInstances #-}
instance Num (Int -> Int) where
f + g = \x -> f x + g x
f * g = \x -> f x * g x
abs f = \x -> abs (f x)
fromInteger n = \x -> fromInteger n
signum f = error "not implemented"
f1 :: Int -> Int
f1 x = x + 1
f2 :: Int -> Int
f2 x = x + 2
f3 :: Int -> Int
f3 = f1 + f2
main = do
print $ f3 0
Run Code Online (Sandbox Code Playgroud)