组成“和长”是什么意思?

时间:2019-11-26 05:41:36

标签: haskell types composition

我正在玩Haskell中的类型,并且偶然发现length . sum是有效的。是否有某种语义上的含义应该允许它起作用,或者这仅仅是类型定义的疣?我已经在下面编写了每个类型定义。

length :: Foldable t => t a -> Int
sum :: (Foldable t, Num a) => t a -> a
(.) :: (b -> c) -> (a -> b) -> a -> c
length . sum :: (Foldable t1, Foldable t2, Num (t1 a)) => t2 (t1 a) -> Int

我能理解的唯一情况是将字符加到一个字符串中,然后就可以得到该字符串的长度。但是,sum只能采用可折叠的数字类型,因此无法使用。

1 个答案:

答案 0 :(得分:6)

这是一个简单的例子。

import Data.Functor.Identity

xs :: [Identity Int]
xs = map Identity [0..9]

result :: Int
result = length . sum $ xs

main :: IO ()
main = print result -- 1

让我们了解发生了什么事。

  1. 首先,我们对xs的所有元素求和。因此,sum xsIdentity 0 + ... + Identity 9,其值为Identity 45。请注意,Num a => Identity aNum的实例。
  2. 接下来,我们找到sum xs的长度。因此,length . sum $ xslength $ Identity 45,其求值为1,因为任何Identity数据结构中都只有一个元素。

如果您查看length . sum的签名,这将很有意义。

length . sum :: (Foldable g, Foldable f, Num (f a)) => g (f a) -> Int

首先,我们遍历g并找到sum中所有f a中的gsum的定义取决于类型f a。结果为f a。然后,我们在结果length中找到f a