Составление функций '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. Почему композиция, которую я написал, не компилируется?
  2. Где мои рассуждения идут не так?

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

МАКСИМАЛЬНАЯ КРАСОТА ДОСТИГЛА.

Другие вопросы по тегам