我有一个模糊的类型变量问题。我喜欢哈斯克尔,但这真的是我仍然无法处理。 问题非常简单,涉及来自Text.Printf的printf。由于问题很普遍,我只是在一些示例代码中:
program = do
d <- addd 4 8
printf "%d" d
addd x y = return (x+y)
当然是printf是导入的。编译器然后在Num和PrintfArg之间给出了一个明显的,模糊的类型变量错误。我只是不知道在哪里适合正确的类型签名。
答案 0 :(得分:2)
有几个地方可以放置类型签名。首先,addd具有最常见的类型(并且最常见的类型是(几乎总是)GHC在您不签名时推断的内容):
addd :: (Monad m, Num a) => a -> a -> m a
你可以通过给addd
一个显式类型签名来限制它只对特定类型起作用,这样它在参数中根本不是多态的,例如:
addd :: Monad m => Int -> Int -> m Int
-- or,
addd :: Monad m => Integer -> Integer -> m Integer
或者,您可以在致电addd
时告知GHC输入类型,例如:
d <- addd 4 (8 :: Integer)
然后类型推断会推断4
和d
都是Integer
s。
最后,您可以为d
提供一种类型。当你使用它时(如果多次使用d
,你只需要一个注释),如下所示:
printf "%d" (d :: Integer)
或者当你设置它时(需要GHC扩展名ScopedTypeVariables
):
{-# LANGUAGE ScopedTypeVariables #-}
[...]
add = do
(d :: Integer) <- addd 4 8
答案 1 :(得分:1)
我会尝试解释你的程序有什么问题。
printf
,如果要输出到控制台,请使用print
或putStrLn
。如果要将类型(其show
实例已定义)转换为字符串,请使用show
。无论如何,这是您的更正程序
import Text.Printf
program :: String
program = do
let d = addd 4 8
printf "%d" d
addd :: Int -> Int -> Int
addd x y = x+y
您可以使用print
作为
program :: IO ()
program = do
print $ addd 4 8
addd :: Int -> Int -> Int
addd x y = x+y
尝试阅读Haskell
上的一些介绍性材料