length (1,2)
возвращает результат, ноПочему вы не можете получить длину (,,)?
length (1, 2, 3)
выдает ошибку. Почему это?
Чтение типов (,)
и (,,)
не помогло.
Edit: Я думаю о длине от Data.Foldable
length :: Foldable t => t a -> Int
length (1,2)
возвращает результат, ноПочему вы не можете получить длину (,,)?
length (1, 2, 3)
выдает ошибку. Почему это?
Чтение типов (,)
и (,,)
не помогло.
Edit: Я думаю о длине от Data.Foldable
length :: Foldable t => t a -> Int
Это является следствием предложения FTP (Foldable-Traversable in 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’
...
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)
вы не видите Складная или проходимые экземпляр, и поэтому length
не определено для этих значений.
Update
(a,b)
Так считается контейнером одного значения b
.
Вы можете увидеть это, наблюдая за вывод этого кода:
import Data.Foldable (fold)
import Data.Monod
foo :: Sum Int
foo = fold (3,4) :: Sum Int
Оценка foo
возвращается Sum {getSum = 4}
.
короткий ответ, потому что это не функция с именем length
, которая принимает (,,) в качестве входных данных.
Существует функция length
которая принимает Складную в качестве входных данных: https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Foldable.html#v:length
Если вы напечатаете это в GHCI:
:i (,)
Вы заметили, что экземпляр Складной
(,,)
не является экземпляром складного.
Ах, я не знал ': t' не сообщал о типах очков. Благодарю. –
Functor
, Traversable
, и наиболее конкретно Foldable
экземпляры для пар несколько спорные. Существуют ситуации, когда они позволяют компилировать код и делать то, что не предназначено. I proposed adding the missing functor instances for triples, etc., и, как показывают последующие темы, это действительно коснулось нерва. Итак, почему не (,,)
имеют пример Foldable
? Потому что сообщество не достигло консенсуса относительно этого.
Спасибо. Интересная ссылка из этой темы: http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html –
@ TheUnfunCat, о, я знаю. Нет сомнений, что существует только один закономерный вариант для «Functor» и «Traversable». Главная проблема - «Складная», которая немного «дикая». Например, 'length' и' null' будут работать на 'Foldable', независимо от того, на самом деле это' Foldable', который вы намереваетесь использовать. Это может привести к сбою неправильного кода. – dfeuer
И если я правильно понимаю, что длина одна, потому что первый элемент в паре считается частью структуры складного каким-то образом, так что на самом деле он имеет только один элемент, а именно последний? –
Да - второй элемент считается содержащимся. Я добавлю что-то об этом в свой ответ. – ErikR