为什么你不能得到(,,)的长度?

The*_*Cat 2 haskell

length (1,2) 
Run Code Online (Sandbox Code Playgroud)

返回结果,但是

length (1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

给出错误.这是为什么?

读类型的(,)(,,)没有帮助.

编辑:我想的是长度 Data.Foldable length :: Foldable t => t a -> Int

dfe*_*uer 7

这对Functor,Traversable尤其是Foldable对的情况有些争议.在某些情况下,它们允许代码编译并执行非预期的操作.我建议为三元组等添加缺少的仿函数实例,并且正如随后的线程所示,这真的触动了一个神经.那么,为什么(,,)有一个Foldable实例?因为社区尚未就此达成共识.


Eri*_*ikR 6

这是FTP (Prelude中可折叠 - 可遍历)提案的结果.

有了它,length现在定义为可折叠的任何东西,并且结果是对的是一个可折叠的实例:

ghci> :i (,)
data (,) a b = (,) a b  -- Defined in ‘GHC.Tuple’
...
instance Monoid a => Applicative ((,) a) -- Defined in ‘GHC.Base’
instance Foldable ((,) a) -- Defined in ‘Data.Foldable’
instance Traversable ((,) a) -- Defined in ‘Data.Traversable’
...
Run Code Online (Sandbox Code Playgroud)

length (a,b) 将永远返回1.

没有为高阶元组定义的可折叠实例.例如,如果检查为三元组定义的类:

ghci> :i (,,)
data (,,) a b c = (,,) a b c    -- Defined in ‘GHC.Tuple’
instance (Bounded a, Bounded b, Bounded c) => Bounded (a, b, c)
instance (Eq a, Eq b, Eq c) => Eq (a, b, c)
instance (Ord a, Ord b, Ord c) => Ord (a, b, c)
instance (Read a, Read b, Read c) => Read (a, b, c)
instance (Show a, Show b, Show c) => Show (a, b, c)
instance (Monoid a, Monoid b, Monoid c) => Monoid (a, b, c)
Run Code Online (Sandbox Code Playgroud)

您没有看到可折叠或可遍历的实例,这就是为什么length没有为这些值定义的原因.

更新

因此(a,b)被认为是单值的容器b.

你可以通过观察这段代码的输出来看到这个:

import Data.Foldable (fold)
import Data.Monod

foo :: Sum Int
foo = fold (3,4) :: Sum Int
Run Code Online (Sandbox Code Playgroud)

评估foo回报Sum {getSum = 4}.