haskell 如何通过递归显示字符串中的整数

gcuhipw9  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(128)

我是新的Haskell和我遇到了一些问题与我的递归解决方案。我将感谢任何和所有的帮助!
我的第一个目标是创建一个函数,检查字符串“A”,“B”和“C”的顺序,并输出一个整数数组,通过递归将每个字符串Map为一个数字。
我的第二个目标是创建一个函数,它可以使用两个整型数组(其中一个是从check_order创建的整数数组(由1、2和3组成),另一个是长度为3的随机整数数组),并返回一个字符串,使得1将被随机整数数组的第一个元素替换,2将被随机整数数组的第二个元素替换,等等。
下面是我的代码:

-- Takes any String consisting of namely A, B, and C and returns an Integer
-- with 1, 2, and 3 that corresponds to each particular character.
check_order :: String -> [Int]
check_order "" = []
check_order (x:xs)
    | x `elem` "A" = 1 : check_order xs
    | x `elem` "B" = 2 : check_order xs
    | otherwise    = 3 : check_order xs
    
-- Takes the integer array generated from check_order and an arbitrary
-- integer array of length 3 and returns a String correlating the check_order
-- array and the arbitrary integer array
number_correction :: Integral n => [n] -> [n] -> String
number_correction [] _ = ""
number_correction (x:xs) num_array
    | x == 1 = show (num_array !! 0) ++ " " ++ number_correction xs num_array
    | x == 2 = show (num_array !! 1) ++ " " ++ number_correction xs num_array
    | otherwise    = show (num_array !! 2) ++ " " ++ number_correction xs num_array
    
main = do
       let test = "ABCBABBAC";
       let num_array = [6, 1, 8];
       print(number_correction(check_order(test), num_array));
       
       --This print statement should print out "6 1 8 1 6 1 1 6 8"

以下是错误日志:

[1 of 1] Compiling Main             ( main.hs, main.o )
main.hs:12:16: error:• Could not deduce(Show n) arising from a use of ‘show’
      from the context: Integral n
        bound by the type signature for:number_correction :: Integral n => [n] -> [n] -> String
        at main.hs:9:1-55
      Possible fix:add (Show n) to the context of
          the type signature for:
            number_correction :: Integral n => [n] -> [n] -> String
    • In the firstargument of ‘(++)’, namely ‘show (num_array !! 0)’
      In the expression:
        show (num_array !! 0) ++ " " ++ number_correction xs num_array
      In anequation for ‘number_correction’:
          number_correction (x : xs) num_array
            | x == 1
            =show (num_array !! 0) ++ " " ++ number_correction xs num_array
            | x == 2
            = show (num_array !! 1) ++ " " ++ number_correction xs num_array
        | otherwise
            = show (num_array !! 2) ++ " " ++ number_correction xs num_array

main.hs:19:31: error:
    • Couldn't match expected type ‘[n0]’
        with actual type ‘([Int], [Integer])’
    • In the first argument of ‘number_correction’, namely
        ‘(check_order (test), num_array)’
      In the first argument of ‘print’, namely
        ‘(number_correction (check_order (test), num_array))’
      In a stmt of a'do' block:
        print (number_correction (check_order (test), num_array))
5jdjgkvh

5jdjgkvh1#

(Int n) => [n] -> [n] -> String没有任何意义。Int是一个具体的类型,那么Int n应该是什么意思呢?

foo = True 37
  • 你试图把某个东西当作函数而不是函数
    你脑海中可能想到的是
number_correction :: Integral n => [n] -> [n] -> String

Int不同,Integral是一个类型 * 类 *。与Java不同,Haskell中的类型和类是完全不同的。特别是,Integral * 是类型级别上的 * 函数。你可以在GHCi中看到这一点:

Prelude> :k Int
Int :: Type
Prelude> :k Integral
Integral :: Type -> Constraint

(传统上,它会显示** -> Constraint*是旧符号,表示类型的种类)。
因此,Integral n确实有意义:将Type -> Constraint应用于Type类型的变量n,从而得到一个约束。约束可以出现在=>箭头的左侧。
你也可以用Int来做一个约束。这需要(足够常见的)-XTypeFamilies扩展,然后你可以写

number_correction :: (n ~ Int) => [n] -> [n] -> String

在这种情况下,你基本上使用了“等于Int的所有类型的类“,这有点傻。Integral类包含类型Int,但也包含其他类型,如IntegerInt32
如果您确实只想允许Int,则只需编写

number_correction :: [Int] -> [Int] -> String

相关问题