Haskell-查找文本中最长的单词

Haskell-查找文本中最长的单词,haskell,text,word,Haskell,Text,Word,我在写一个函数来查找文本中最长的单词时遇到了一个问题 输入:包含大量单词的字符串。例:“我是个年轻人,我有一栋大房子。” 结果是5,因为文本中最长的单词有5个字母(young和house) 我刚开始学哈斯克尔。我试过: import Char import List maxord' (str:strs) m n = if isAlpha str == True then maxord'(strs m+1 n) else if m >= n then

我在写一个函数来查找文本中最长的单词时遇到了一个问题

输入:包含大量单词的字符串。例:
“我是个年轻人,我有一栋大房子。”

结果是5,因为文本中最长的单词有5个字母(young和house)

我刚开始学哈斯克尔。我试过:

import Char
import List

maxord' (str:strs) m n = 
    if isAlpha str == True
    then maxord'(strs m+1 n)
else    if m >= n
        then maxord'(strs 0 m)
    else    maxord'(strs 0 n)

maxord (str:strs) = maxord' (str:strs) 0 0
我想返回
n
作为结果,但我不知道怎么做,而且代码似乎也有问题


有什么帮助吗?谢谢

尝试将您的任务拆分为多个子任务。我建议像这样拆分它:

if ...
then ...
else if ...
     then ...
     else ...
  • 将字符串转换为单词列表。例如,您的示例字符串变为

    ["I","am","a","young","man","and","I","have","a","big","house"]
    
  • map length
    覆盖列表。这将计算单词长度。例如,步骤1中的列表变为

    [1,2,1,5,3,3,1,4,1,3,5]
    
  • 查找字符数最多的单词。对此,您可以使用
    最大值

  • 您可以使用操作符
    (.)
    组合这些步骤,该操作符将两个函数连接在一起。例如,如果执行步骤1的功能被称为
    toWords
    ,则可以在一行中执行整个任务:

    maxord = maximum . map length . toWords
    

    toWords
    的实现留给读者作为练习。如果您需要帮助,请随时写评论。

    这里有几个问题。让我们从语法开始

    如果
    else
    零件属于
    ,则它们的缩进应与
    相同或更多,例如:

    if ...
    then ...
    else if ...
         then ...
         else ...
    
    接下来是函数应用程序。与许多其他语言不同,在Haskell中,括号仅用于分组和元组。由于函数应用程序在Haskell中非常常见,因此我们使用了最轻量级的语法,即空格。因此,为了将函数
    maxord'
    应用于参数
    strs
    m+1
    n
    ,我们编写
    maxord'strs(m+1)n
    。请注意,由于函数应用程序具有最高优先级,我们必须在
    m+1
    周围添加括号,否则它将被解释为
    (maxord'strs m)+(1 n)

    语法就是这样。下一个问题是语义问题,即递归没有基本情况。使用模式
    (str:strs)
    ,您已经指定了在剩下一些字符时要执行的操作,但是没有指定在到达字符串末尾时要执行的操作。在本例中,我们希望返回
    n
    ,因此我们为此添加了一个case

    maxord' [] m n = n
    
    因此,固定的
    maxord'

    maxord' [] m n = n
    maxord' (str:strs) m n = 
        if isAlpha str == True
        then maxord' strs (m+1) n
        else if m >= n
             then maxord' strs 0 m
             else maxord' strs 0 n
    

    但是,请注意,这个解决方案不是很惯用。它使用显式递归,
    if
    表达式而不是Guard,将布尔值与
    True
    进行比较,具有非常迫切的感觉。更惯用的解决方案是这样的

    maxord = maximum . map length . words
    
    这是一个简单的函数链,
    words
    将输入拆分为一个单词列表,
    map length
    将每个单词替换为其长度,
    maximum
    返回这些长度中的最大值


    尽管如此,请注意它与您的代码并不完全相同,因为拆分输入时,
    words
    函数使用的标准略有不同。

    存在一些问题

    递归没有终止。处理整个输入时,您希望返回
    n

    maxord' [] _ n = n
    
    语法:

    maxord'(strs 0 m)
    
    这意味着调用使用参数
    0
    m
    应用
    strs
    ,然后将其用作
    maxord
    的参数。你不想做的是:

    maxord' strs 0 m
    
    m+1
    应该是
    (m+1)

    您可能希望处理空字符串,但
    maxord
    不允许

    maxord s = maxord' s 0 0
    

    应该这样做。这里有几个微妙之处
    maxord'
    不应泄漏到名称空间,请使用
    where
    (max m n)
    比您使用的if-then-else更简洁。并检查其他答案,看看如何通过将内置内容连接在一起来构建解决方案。递归更难阅读。

    toWords的最佳实现可能是:“toWords=words”。@ben No。单词还可以计算标点和数字。