haskell - 如何推断liftM2 (==) id和(\x->x+1) id的类型

标签 haskell type-inference

我正在学习 Haskell。有人可以解释如何推断这两种类型以及 Num (a -> a) 是什么意思?

liftM2 (==) id :: Eq a => (a -> a) -> a -> Bool


(\x->x+1) id :: Num (a -> a) => a -> a

最佳答案

在第一种情况下,我们有

liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
(==) :: Eq a => a -> a -> Bool

通过设置 a1=aa2=a我们得到
liftM2 (==) :: (Eq a, Monad m) => m a -> m a -> m Bool

现在棘手的是有 a Monad instance for the function type .
instance Monad ((->) r) where
    return = const
    f >>= k = \ r -> k (f r) r

因此,类型为 r -> a 的函数可以通过哪里Monad a => m a是期待。自 id :: a -> a我们得到 r=a , m a = a -> am Bool = a -> Bool , 导致
liftM2 (==) id :: (Eq a) => (a -> a) -> (a -> Bool)

对于第二种类型,该类型签名所说的是函数类型 (a -> a) 有一个 Num 实例。 .

Haskell 数字文字是多态的,((\x -> x + 1) id)实际上是以下内容的语法糖:
((\x -> x + (fromInteger 1)) id)

其中,通过 β-reduce 是
id + (fromInteger 1)

这假设 (fromInteger 1) 是一个函数,并且有一种方法可以将两个函数与 + 相加。运算符(operator)。默认情况下这是不可能的,但是 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

关于haskell - 如何推断liftM2 (==) id和(\x->x+1) id的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32491665/

相关文章:

Haskell:对于 Map 中的每个 (k,v),用 k 和 v 执行 IO()

Kotlin 和 RxJava 类型推断失败

c++ - VBO 一般几何

haskell - Haskell中自动函数约束推导的类型约束

haskell - Haskell 中以下函数最通用的类​​型

scala:classOf[]、异常和::列出奇怪行为的运算符

java - 使用本地类型推断的交叉类型的有用应用

c# - Lambda 表达式类型推断在继承链中是不同的。为什么?

scala - 如何在 Scala 中将对象用作模块/仿函数?

haskell - (>>=) 和 (>=>) 之间的区别