【问题标题】:Type casting within a recursive function in Haskell在 Haskell 的递归函数中进行类型转换
【发布时间】:2021-03-28 02:55:22
【问题描述】:

我正在学习 Haskell 和递归,Haskell 中的不同类型让我很头疼。我正在尝试创建一个递归函数,它将采用 32 位二进制数字符串并将其转换为十进制数。我认为我对递归如何工作的想法很好,但是在 Haskell 中实现它让我头疼。这是我目前所拥有的:

bin2dec :: String -> Int
bin2dec xs = ""
bin2dec (x:xs) = bin2dec xs + 2^(length xs) *  x

该函数应该取一个 32 位数字字符串,然后取出字符串的第一个字符。例如,“0100101010100101”变为“0”和“100101010100101”。然后它应该将第一个字符转换为整数并将其乘以字符串其余部分的 2^length 并再次将其添加到函数调用中。所以如果 32 位字符串中的第一个字符是“1”,那么它就变成了 1 * 2^(31) + 递归函数调用。

但是,每当我尝试编译它时,它都会返回:

traceProcP1.hs:47:14: error:
    * Couldn't match type `[Char]' with `Int'
      Expected: Int
        Actual: String
    * In the expression: ""
      In an equation for `bin2dec': bin2dec xs = ""
   |
47 | bin2dec xs = ""
   |              ^^

traceProcP1.hs:48:31: error:
    * Couldn't match expected type `Int' with actual type `Char'
    * In the second argument of `(+)', namely `2 ^ (length xs) * x'
      In the expression: bin2dec xs + 2 ^ (length xs) * x
      In an equation for `bin2dec':
          bin2dec (x : xs) = bin2dec xs + 2 ^ (length xs) * x
   |
48 | bin2dec (x:xs) = bin2dec xs + 2^(length xs) *  x
   |                               ^^^^^^^^^^^^^^^^^^

我知道这与更改数据类型有关,但我在 Haskell 中进行类型转换时遇到问题。我尝试使用 read 输入 x 并且我尝试制作将“0”变成 0 和“1”变成 1 的保护,但我无法让这些工作。任何帮助将不胜感激。

【问题讨论】:

  • 除了打字问题外,值得指出的是您的模式顺序错误。匹配是自上而下的,并在第一个匹配处停止 - 所以一旦修复它以便编译,任何字符串都会得到 0。您需要切换顺序或更改模式,以便它不会捕获所有内容,而只会捕获空字符串。

标签: function haskell recursion casting type-conversion


【解决方案1】:

没有演员表。如果您想从一种类型转换为另一种类型,则需要一个具有正确类型签名的函数才能执行此操作。在 Haskell 中寻找任何函数时,Hoogle 通常是一个好的开始。在这种情况下,您正在寻找Char -> Int,它有几个有希望的选项。我看到的第一个是digitToInt,听起来很适合你。

但如果您更愿意自己做,使用模式匹配编写具有所需行为的函数非常容易:

bit :: Char -> Int
bit '0' = 0
bit '1' = 1
bit c = error $ "Invalid digit '" ++ [c] ++ "'"

【讨论】:

  • 我明白了。谢谢!这更有意义。在没有像 0 和 1 这样的少量选项并且您试图将它们全部转换的情况下,您会怎么做?
  • 没有办法:模式匹配是在 Haskell 中使用数据的基本方式。您要么需要编写更多模式,要么使用其他已经为您完成的功能,例如 ord :: Char -> Int
  • @EMC, ord 来自 Data.Char 并且与前奏中可用的多态 fromEnum 函数相同(对于字符)(没有导入)。这些函数实际上并不匹配所有可能的字符;他们使用Char 的内部表示来高效、紧凑地完成工作。
猜你喜欢
  • 2022-01-06
  • 2021-09-06
  • 1970-01-01
  • 2015-05-25
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2019-02-28
相关资源
最近更新 更多