I wrote a function count :: Char -> String -> Int
that counts the number of occurrences of a Char
inside a String
. Code sample:
module Main where
import Data.List
main :: IO ()
main = do
print $ count 'a' "abcaaba"
count :: Char -> String -> Int
count = length . elemIndices
The compile error I get is
* 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
OK, I could write count x y = length $ elemIndices x y
which works. But I argue we have
(1) (.) :: (b -> c) -> (a -> b) -> a -> c
(2) elemIndices :: Eq a => a -> [a] -> [Int]
and
(3) length :: [a] -> Int
If count
shall be a composition of (2) and (3) then in (1) we need obviously a = Char -> [Char]
and c = Int
. And if b = [Int]
we get
(1') (.) :: ([Int] -> Int) -> (Char -> [Char] -> [Int]) -> Char -> [Char] -> Int
which means I can compose (2) and (3) to get Char -> [Char] -> Int
.
Questions:
- Why is the composition I wrote failing to compile?
- Where is my reasoning going wrong?