在具有多个 return 值的 Haskell `do` 中输入不匹配

Type mismatches in Haskell `do` with multiple return values

我有以下代码,但在编译时出现了几个错误。我可以 return 两个变量作为来自 do 语句的元组吗?

Couldn't match type ‘[]’ with ‘(,) String’
      Expected type: (String, Char)
        Actual type: String
    • In a stmt of a 'do' block: f <- string_prog (g)

Couldn't match expected type ‘(String, t0)’
                  with actual type ‘Int’
    • In a stmt of a 'do' block: tx <- mult_prog x y

Couldn't match expected type ‘t0 -> Int’ with actual type ‘Char’
    • The function ‘f’ is applied to one argument,
      but its type ‘Char’ has none
    mult_prog :: Int -> Int -> Int
    mult_prog one1 one2 = one1 * one2
                            
    string_prog :: String -> String
    string_prog s = ("  " ++ s ++ "   ")     
    
    
    do_prog :: String -> Int -> Int -> (String, Int)
    
    do_prog g x y =   do f <- string_prog(g)  
    
                         tx <- mult_prog x y
    
                         return $ f tx 

<- 用于从 monad 中“提取”值,而您的值不是(至少不是您认为的那样)。 return 用于在 monad 中包装一个值,而您的 return 值不是。相反,使用 let 并且只有一个元组作为最终值:

mult_prog :: Int -> Int -> Int
mult_prog one1 one2 = one1 * one2
                        
string_prog :: String -> String
string_prog s = ("  " ++ s ++ "   ")     


do_prog :: String -> Int -> Int -> (String, Int)
do_prog g x y = do let f = string_prog g
                   let tx = mult_prog x y
                   (f, tx)

请注意,您甚至不需要 do,只需使用 let...in:

mult_prog :: Int -> Int -> Int
mult_prog one1 one2 = one1 * one2
                        
string_prog :: String -> String
string_prog s = ("  " ++ s ++ "   ")     


do_prog :: String -> Int -> Int -> (String, Int)
do_prog g x y = let f = string_prog g
                    tx = mult_prog x y
                 in (f, tx)