了解“ 5 1”的类型

世界末日

我在这里使用了Haskell解释器:https//tryhaskell.org/

当我提供输入时,5 1它告诉我-我假设它是类型-表达式的类型是(Num a, Num (a -> t)) => t

λ 5 1
:: (Num a, Num (a -> t)) => t

现在,我试图理解如何解释这一点,这就是我的想法。

a是任何Num类型,也是a -> t该表达式产生某种类型t,该类型是从理论上将1(type a)应用于5(type a -> t)而产生的。

这真的让我感到困扰,因为我不明白约束的Num (a -> t)意义。从理论上讲,这似乎是正确的解释,但我找不到证明。


解释正确

这是有道理的,因为它Num是一个多态类型-可以是一个函数。

比克利尔

在Haskell中,数字是多态的。当你写类似

5

编译器将其转换为fromInteger (5 :: Integer) :: Num a => a编译器事先不知道要使用哪个实例,因此最好从上下文中进行猜测。如果具有5 1,则第一个数字是多态Num类型,也必须是一个函数。第二个数字只是看成一个Num,所以这很正常。

但是您可能会问:“数字如何成为函数?” 如果世界上的一切都有意义,那么数字将不是函数,但实际上您可以为它们写一个或多或少表现的实例:

{-# LANGUAGE FlexibleInstances #-}

instance Num a => Num (a -> a) where
    fromInteger a = const (fromInteger a)
    a + b = \c -> a c + b c
    a * b = \c -> a c * b c
    abs a = \c -> abs (a c)
    signum a = \c -> signum (a c)
    negate a = \c -> negate (a c)

这满足了定义,但是可能不是很有用。例如:

> let x = 1 :: Int -> Int; y = 2 :: Int -> Int
> x + y $ 0
3
> x + y $ 102089
3
> x + y $ undefined
3

因此,这里的参数与表达式无关,甚至没有求值。怎么样一个更有趣的:

> let x = (+10); y = (*10)
> x + y $ 0    -- x 0 + y 0 = 0 + 10 + 0 * 10
10
> x + y $ 1    -- x 1 + y 1 = 1 + 10 + 1 * 10
21
> x + y $ 2
32

依此类推。我敢肯定有人会为此找到一个有趣的用例,但我不建议这样做,这显然不是很直观。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章