【问题标题】:Split strings into lists with Haskell使用 Haskell 将字符串拆分为列表
【发布时间】:2012-02-09 00:13:59
【问题描述】:

背景故事:上周我一直在努力解决这个问题,阅读了Learn You A Haskell 和在线教程,但我无法弄清楚。

我在理解列表推导和递归方面取得了很大进展,但这个问题是我仍然遇到的一件事。

问题:我正在尝试将一个字符串(或我认为是字符串)转换为一个分割列表。这是我到目前为止的代码(再次感谢 Jan 的帮助)。它导入 .txt 文件的内容。

import System.Environment

main :: IO ()
main = do
     args <- getArgs
     if null args
       then putStrLn "usage: ./pattern dataset.txt"
       else do contents <- readFile $ head args
               putStrLn $ "Filer1: " ++ filterLower(contents)
               convert' contents

filterLower :: String -> String
filterLower st = [ c | c <- st, c `elem` ['A'..'Z']]

我尝试制作自己的转换函数:

convert' :: String -> [String]
convert' x = (x:[])

它有效,但不适用于这个问题。

任何帮助将不胜感激。

错误:这是我经常遇到的错误。

Couldn't match expected type `IO ()' with actual type `[String]'
    In the return type of a call of `convert''
    In the expression: convert' contents
    In the expression:
      do { contents <- readFile $ head args;
             putStrLn $ "-: " ++ filterLower contents;
           convert' contents }

【问题讨论】:

  • 您遇到的错误/问题是什么?
  • 我刚刚在帖子中添加了我的错误。
  • 您在致电convert' 后会发生什么?看起来你只是想把结果扔掉:你没有尝试打印它或任何东西。
  • 我不明白你所说的“分割字符串”是什么意思。
  • 通过“分割字符串”我的意思是把这样的“引号中的句子”变成这样的东西 ["A", "sentence", "in", "a", "列表”]。

标签: string list haskell io


【解决方案1】:

问题是convert' 的结果是一个字符串列表,但您试图将其用作 IO 操作。你必须对结果做点什么。例如,

print $ convert' contents

会将结果打印到屏幕上。或者你可以使用,例如mapM_ putStrLn 将每个元素打印在自己的行上。或者你可以给它一个名字,然后继续写语句,比如:

let converted = convert' contents
...

根据您的评论,您尝试划分字符串的方式似乎是将其转换为单词列表,例如convert' "Hello world"["Hello", "world"]。在这种情况下,您根本不需要 convert' — 标准的 words 函数就是这样做的!所以你可以只使用words contents 而根本不定义convert'

【讨论】:

  • 我记得 Jan 告诉过我关于单词的事情,但我没有意识到这是一个函数。但我现在应该知道 Haskell 中的一切都是函数。 :D 我现在回到正轨。感谢您的帮助。
  • @SubtleArray,FWIW,并不是说 Haskell 中的所有东西都是函数。例如,字符串"this is not a function" 是真实的。只有函数才是函数 ;-)
【解决方案2】:

convert' :: String -&gt; [String],所以convert' contents :: [String] 只是一个字符串列表。但是你已经把它放在了一个 IO 块中,

do contents <- readFile whatever
   putStrLn $ ...
   convert' contents

只有IO something 类型的表达式可以出现。有一种简单的方法可以将无 IO 表达式变成 IO 事物,只需 return 它:

do contents <- readFile ...
   putStrLn $ ...
   return $ convert' contents

输入正确。但是这个do-block的类型是IO [String],所以它与main的声明类型不匹配。如何解决这个问题取决于你希望你的程序做什么。

【讨论】:

  • 我明白了。它就像一个 C++ 函数,其功能受其类型的限制。谢谢你的澄清。我对 Haskell 很陌生,我仍在尝试绕过语法。
【解决方案3】:

我不明白你想在这里做什么,但最大的问题是你没有正确使用do-block。 main 具有 IO () 类型,这意味着两个约束:

  • 对于某些a,do-block 中的每个“裸”语句(没有&lt;- 的语句)都必须具有IO a 类型。
  • do-block 中的最后一条语句必须具有IO () 类型;您的最终语句的类型为 [String] (因此您得到的错误)。该类型最简单的语句是return ()

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2012-06-13
    • 2019-04-16
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多