Составление функций 'length' и 'elemIndices'
Я написал функцию count :: Char -> String -> Int
который считает количество вхождений Char
внутри String
, Пример кода:
module Main where
import Data.List
main :: IO ()
main = do
print $ count 'a' "abcaaba"
count :: Char -> String -> Int
count = length . elemIndices
Я получаю ошибку компиляции
* Couldn't match type `Int' with `String -> Int'
Expected type: Char -> String -> Int
Actual type: Char -> Int
* Possible cause: `(.)' is applied to too many arguments
In the expression: length . elemIndices
In an equation for `count': count = length . elemIndices
Хорошо, я мог бы написать count x y = length $ elemIndices x y
который работает. Но я утверждаю, что у нас есть
(1) (.) :: (b -> c) -> (a -> b) -> a -> c
(2) elemIndices :: Eq a => a -> [a] -> [Int]
а также
(3) length :: [a] -> Int
Если count
будет состав из (2) и (3), то в (1) нам нужно a = Char -> [Char]
а также c = Int
, И если b = [Int]
мы получаем
(1') (.) :: ([Int] -> Int) -> (Char -> [Char] -> [Int]) -> Char -> [Char] -> Int
что означает, что я могу составить (2) и (3), чтобы получить Char -> [Char] -> Int
,
Вопросы:
- Почему композиция, которую я написал, не компилируется?
- Где мои рассуждения идут не так?
1 ответ
->
в типах прав ассоциативно:
elemIndices :: Eq a => a -> [a] -> [Int]
средства
elemIndices :: Eq a => a -> ([a] -> [Int])
Когда вы используете elemIndices
на правой стороне (.) :: (b -> c) -> (a' -> b) -> a' -> c
, у тебя есть
a' = a
b = [a] -> [Int]
И это где вещи ломаются, потому что length
не берет [a] -> [Int]
(функция) в качестве входных данных; это хочет список.
Вместо этого вы можете:
count x y = length (elemIndices x y)
Это так же, как (по определению (.)
):
count x y = (length . elemIndices x) y
Это сокращение:
count x = length . elemIndices x
Вы, вероятно, должны остановиться здесь, потому что здесь все немного сходит с ума.
Префиксная нотация:
count x = (.) length (elemIndices x)
Значение (.)
:
count x = ((.) length . elemIndices) x
Это сокращение:
count = (.) length . elemIndices
Или используя раздел оператора:
count = (length .) . elemIndices
Но подождите, это еще не все!
Префиксная нотация:
count = (.) ((.) length) elemIndices
Значение (.)
:
count = (((.) . (.)) length) elemIndices
Удаление лишних паренов:
count = ((.) . (.)) length elemIndices
Префиксная нотация:
count = (.) (.) (.) length elemIndices
МАКСИМАЛЬНАЯ КРАСОТА ДОСТИГЛА.