Haskell 组合函数';长度';和';电子设备';

Haskell 组合函数';长度';和';电子设备';,haskell,function-composition,Haskell,Function Composition,我编写了一个函数count::Char->String->Int,它计算字符串中出现的Char的次数。代码示例: module Main where import Data.List main :: IO () main = do print $ count 'a' "abcaaba" count :: Char -> String -> Int count = length . elemIndices 我得到的编译错误是 * Couldn't match t

我编写了一个函数
count::Char->String->Int
,它计算
字符串中出现的
Char
的次数。代码示例:

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
好的,我可以写下有效的
countxy=length$elemindicesxy
。但我认为我们有

(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]->Int

这意味着我可以组合(2)和(3)得到
Char->[Char]->Int

问题:

  • 为什么我写的作文没能编译
  • 我的推理哪里出错了

  • 类型中的
    ->
    是右关联的:

    elemIndices :: Eq a => a -> [a] -> [Int]
    
    意味着

    当您在
    (:(b->c)->(a'->b)->a'->c
    的右侧使用
    elemIndices
    时,您有

    • a'=a
    • b=[a]->[Int]
    这就是问题的症结所在,因为
    length
    没有将
    [a]->[Int]
    (函数)作为输入;它需要一份清单


    你可以做的是:

    count x y = length (elemIndices x y)
    
    这与(根据
    ()
    )的定义)相同:

    预计到达时间减少:

    count x = length . elemIndices x
    
    count = (.) length . elemIndices
    
    你应该停在这里,因为这是事情变得有点疯狂的地方


    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    
    ()
    的定义:

    预计到达时间减少:

    count x = length . elemIndices x
    
    count = (.) length . elemIndices
    
    或使用操作员部分:

    count = (length .) . elemIndices
    

    但是等等,还有更多

    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    
    ()
    的定义:

    删除冗余参数:

    count = ((.) . (.)) length elemIndices
    
    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    

    达到最大美感。

    ->
    在类型中是正确的:

    elemIndices :: Eq a => a -> [a] -> [Int]
    
    意味着

    当您在
    (:(b->c)->(a'->b)->a'->c
    的右侧使用
    elemIndices
    时,您有

    • a'=a
    • b=[a]->[Int]
    这就是问题的症结所在,因为
    length
    没有将
    [a]->[Int]
    (函数)作为输入;它需要一份清单


    你可以做的是:

    count x y = length (elemIndices x y)
    
    这与(根据
    ()
    )的定义)相同:

    预计到达时间减少:

    count x = length . elemIndices x
    
    count = (.) length . elemIndices
    
    你应该停在这里,因为这是事情变得有点疯狂的地方


    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    
    ()
    的定义:

    预计到达时间减少:

    count x = length . elemIndices x
    
    count = (.) length . elemIndices
    
    或使用操作员部分:

    count = (length .) . elemIndices
    

    但是等等,还有更多

    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    
    ()
    的定义:

    删除冗余参数:

    count = ((.) . (.)) length elemIndices
    
    前缀表示法:

    count x = (.) length (elemIndices x)
    
    count = (.) ((.) length) elemIndices
    
    count = (.) (.) (.) length elemIndices
    

    达到了最大的美感。

    在许多哈斯克尔的书籍和教程中,字里行间提到的哈斯克尔的一些基础知识有时会被跳过或忽略。这篇文章很值得一看。在许多Haskell的书籍和教程中,在行间提到的Haskell的一些基础知识有时会被跳过或忽略。这篇文章很值得一看。谢谢你们给出了这个非同寻常的答案。它不仅内容全面、信息丰富,而且很有趣!:-)谢谢你这个非同寻常的回答。它不仅内容全面、信息丰富,而且很有趣!:-)