【问题标题】:Problem differentiating between [Char] and [[Char]] in Haskell在 Haskell 中区分 [Char] 和 [[Char]] 的问题
【发布时间】:2021-06-24 02:58:48
【问题描述】:

所以我有这个函数应该返回一个字符串(或 [Char])。这是它的一个非常简单的版本:

test :: Int -> Int -> [Char]
test n1 n2 = do
    if n1 >= n2 then return "return 1"
    else do
        (...)
        return "return 2"

现在据我了解,“return 1”和“return 2”是字符串。它们应该具有 [Char] 类型。但是由于某种原因,当我编译它时,出现以下错误:

Cards.hs:284:22: error:
    • Couldn't match type ‘[Char]’ with ‘Char’
      Expected type: [Char]
        Actual type: [[Char]]
    • In the expression: return "return 1"
      In a stmt of a 'do' block:
        if n1 >= n2 then return "return 1" else do return "return 2"
      In the expression:
        do if n1 >= n2 then return "return 1" else do return "return 2"
    |
284 |     if n1 >= n2 then return "return 1"

当程序将这些字符串识别为 [[Char]] 时,谁能告诉我?因为我也尝试过在返回之前连接返回值,当我这样做时,它识别为类型 [Char]。

【问题讨论】:

  • 简短回答:除非你知道你需要它们,否则不要使用 doreturn
  • 这是由于return,这意味着您将项目包装在一个单子上下文中,这里该上下文是一个列表,这意味着您创建一个单例列表。
  • @WillemVanOnsem 请问我该如何解决这个问题?
  • 基本上if n1 > n2 then "return 1" else "return 2"

标签: haskell types functional-programming


【解决方案1】:

当程序将这些字符串识别为[[Char]]时,谁能告诉我?

您正在使用do 块。这意味着您正在使用 monad。列表是一个单子。 return :: Monad m => a -> m a 将项目包装在单子上下文中。对于因此意味着您“返回”的值被包装在单例列表中的列表。

我建议不要在您了解 monad 之前使用 doreturn,尤其是因为 return 与 Python 或 Java 等命令式语言的语义不同例子。

您可以在这里使用警卫并将其实现为:

test :: Int -> Int -> [Char]
test n1 n2
    | n1 >= n2 = "return 1"
    | otherwise = "return 2"

【讨论】:

  • 我可以在“否则”之后使用 do 吗?因为真正的函数要复杂得多,除了返回一个字符串之外,还需要做很多其他的事情。
  • @bobthesnob:没有。如果您需要使用 I/O,那么您将需要一个 IO [Char],如果 otherwise 只是意味着更多条件,您可以添加额外的防护。您还可以使用辅助函数来简化实现。 Haskell 中的函数通常只包含几行代码。
猜你喜欢
  • 1970-01-01
  • 2013-03-22
  • 2011-11-25
  • 1970-01-01
  • 2021-07-16
  • 2012-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多