【问题标题】:Understanding Haskell Type了解 Haskell 类型
【发布时间】:2016-06-01 01:27:12
【问题描述】:

我已经设法实现了一个模拟过滤器功能(经过多次尝试)

filter' :: (Num a, Eq a) => (a -> Bool) -> [a] -> [a]
filter' a [] = []
filter' a (x:xs) = if a x
  then x : filter' a xs
  else filter' a xs

我不太清楚的是类型声明

filter' :: (Num a, Eq a) => (a -> Bool) -> [a] -> [a]
-- filter' (<10) [1,2,3] 
-- output = []

我们传入(&lt;10) [1,2,3]。然而,在类型声明(a -&gt; Bool) 中,我们以递归方式传入来自列表的 a,输出为真或假。但是如何表达测试(&lt;10)? 我们为什么不添加另一个 Bool 呢?

【问题讨论】:

  • 在哪里添加另一个Bool
  • ( Bool)。 [1,2,3] 是一个列表,类型为 [a]。过滤器函数接受这个函数和一个列表并返回另一个列表。

标签: haskell


【解决方案1】:

filter' 函数的类型之所以受到限制,是因为您已声明它是。如果不声明类型,编译器会推断出更宽容的类型:(a -&gt; Bool) -&gt; [a] -&gt; [a]。这和内置的filter函数是同类型的:

Prelude> :type filter
filter :: (a -> Bool) -> [a] -> [a]

表达式(&lt; 10) 是一个所谓的section。这是一个部分应用的函数。

运算符&lt;本身就是一个函数:

Prelude> :type (<)
(<) :: Ord a => a -> a -> Bool

您可以将其解读为:&lt; 是一个接受两个参数的函数,都是泛型类型a。类型a 必须属于类型类Ord。当您使用这两个值调用&lt; 时,将返回一个Bool 值。

由于 Haskell 函数是 curried,因此您可以仅使用部分参数调用函数。返回值是一个“等待剩余参数”的新函数:

Prelude> :type (< 10)
(< 10) :: (Num a, Ord a) => a -> Bool

这种类型受到更多限制,因为文字 10 被推断为属于​​ Num 类型类。由于 &lt; 正在使用中,因此 (Ord) 的原始约束仍然有效。

表达式[1,2,3] 被编译器推断为:

Prelude> :type [1,2,3]
[1,2,3] :: Num t => [t]

这些值都属于Num 类型类。当您将所有这些类型一起使用时,您会得到所有推断类型的并集:

Prelude> :type filter (< 10) [1,2,3]
filter (< 10) [1,2,3] :: (Num a, Ord a) => [a]

Num 类型类是因为使用了字面量而被推断出来的,Ord 类型类是因为使用了&lt; 运算符而被推断出来的。

【讨论】:

    猜你喜欢
    • 2014-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多