У меня возникли проблемы с составом и типами функций. Я хотел бы составить filter
(который возвращает список) с len
, который принимает список в качестве аргумента (технически Foldable
, но я упрощаю здесь). Глядя на типы все это, как и ожидалось:Haskell: Типы функциональной композиции, не соответствующие
> :t length
length :: Foldable t => t a -> Int
> :t filter
filter :: (a -> Bool) -> [a] -> [a]
Так что теперь я ожидал бы тип (len . filter)
быть
(length . filter) :: (a -> Bool) -> [a] -> Int
в то время как в действительности
> :t (length . filter)
(length . filter) :: Foldable ((->) [a]) => (a -> Bool) -> Int
Так что, кажется, я потерял некоторые аргументы. Является ли он включенным в требования Foldable
каким-то образом я не понимаю?
Обратите внимание, что все работает, как ожидалось, если я частичное применение:
> let myFilter = filter odd
> :t myFilter
myFilter :: Integral a => [a] -> [a]
> :t (length . myFilter)
(length . myFilter) :: Integral a => [a] -> Int
> (length . myFilter) [1,2,3]
2
Чтобы получить тип композиции, которую вы ожидаете, каждая функция, которую вы составляете, должна принимать «один» аргумент. Я помещаю его в кавычки, потому что все функции принимают один аргумент. См. Больше [здесь] (https://wiki.haskell.org/Currying) – pdexter
Обратите внимание, что '(length. Filter) x y' является' length (filter x) y', а не 'length (filter x y)'. Кроме того, 'filter' на самом деле является функцией, принимающей _one_ argument' a-> Bool' и возвращающей функцию '[a] -> [a]' (вызывать currying), которую композиция пытается передать на 'length'. – chi
Если что-то вроде 'Num [a]' или ничего с '(->)' появляется в ограничении (т.е. слева от '=>'), это обычно признак того, что вы в основном создали ошибку типа , но GHC слишком вежлив, чтобы называть его таким, потому что кто-то мог в принципе определить какой-то нелепый экземпляр класса, который сделает его законным. – leftaroundabout