2

Я пытаюсь написать что-то подобное в Haskell (.):Как использовать в Haskell

length . nub . intersect 

, но он не работает.

*Main Data.List> :t intersect 
intersect :: Eq a => [a] -> [a] -> [a] 
*Main Data.List> :t nub 
nub :: Eq a => [a] -> [a] 
*Main Data.List> :t length 
length :: [a] -> Int 

В зависимости от типа, я понимаю, что intersect возвращает тип [a] и жертвует nub, который занимает ровно тип [a], то также возвращает тип [a] к length, затем, наконец, возвращение должно Int. Что с этим не так?

+1

На самом деле, 'intersect' возвращает тип' [а] -> [а] '. '((длина. нуб).). intersect' будет делать то, что вы хотите, но мое понимание здесь слишком слабое, чтобы ответить. – Franky

+0

см. Также: http://www.haskell.org/haskellwiki/Pointfree#Dot –

ответ

6

Проблема здесь состоит в том, что intersectпринимает 2 аргумент (в некотором смысле)

вы можете предоставить один из аргументов в явном виде:

> let f a = length . nub . intersect a 
> :t f 
f :: Eq a => [a] -> [a] -> Int 

или вы можете использовать забавный оператор как (.:) = (.) . (.) :

> let (.:) = (.) . (.) 
> :t length .: (nub .: intersect) 
length .: (nub .: intersect) :: Eq a => [a] -> [a] -> Int 

вот версия, в которой вам не нужны парсеры:

импорт Data.List

infixr 9 .: 

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d 
(.:) = (.).(.) 

f :: Eq a => [a] -> [a] -> Int 
f = length .: nub .: intersect 
+1

Спасибо! Теперь я наконец понял, что значит «.:» Означает сейчас! – user3928256

4

Я предполагаю, что это основано на комментариях в вашем предыдущем вопросе, где @CarstenKönig mentions (.) . (.).

Прежде всего, length . nub . intersect не может работать. Ваши типы:

(.)  ::   (b -> c) -> (a -> b) -> (a -> c) 
length ::   [a] -> Int 
nub  :: Eq a => [a] -> [a] 
intersect :: Eq a => [a] -> [a] -> [a] ~ [a] -> ([a] -> [a]) 

Как вы можете видеть, intersect имеет неправильный тип, в контексте (.), параметр типа b будет заменен ([a] -> [a]), который не является типом первого аргумента nub «s ,

+0

О, верно! Благодаря! Он основан на первом вопросе;) – user3928256

2

Я бы сказал это: сначала напишите свой код «немой», а затем реорганизовать его для использования (.). После некоторой практики композиционный оператор станет похож на вторую природу.

Таким образом, вы бы сначала написать:

yourFunction xs ys = length (nub (intersect xs ys)) 

Что (.) позволяет сделать это избавиться (синтаксически) последнего аргумента внутренней функции, все все скобки. В этом случае этот аргумент ys:

yourFunction xs = length . nub . intersect xs