![](/img/trans.png)
[英]Haskell: Rigid type variable error when pattern matching bind operator
[英]Type error in Haskell when pattern matching against Maybe with Show constraint
import Data.Maybe
f :: (Show t) => Maybe t -> IO ()
f Nothing = putStrLn "Nothing!"
f (Just x) = putStrLn $ "The number is " ++ (show x)
main = do
f Nothing
这给出:
foo.hs:7:3:
No instance for (Show a0) arising from a use of ‘f’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
...plus 22 others
In a stmt of a 'do' block: f Nothing
In the expression: do { f Nothing }
In an equation for ‘main’: main = do { f Nothing }
foo.hs:7:3:
No instance for (Show a0) arising from a use of ‘f’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
...plus 22 others
In a stmt of a 'do' block: f Nothing
In the expression: do { f Nothing }
In an equation for ‘main’: main = do { f Nothing }
如何解决这种代码和平问题? 重点是安全地打印可显示的内容。 我认为(Show t)=>也许t可以被分解为Nothing和Just x。
假设您是编译器,并且您正在尝试键入检查程序:
main = do
f Nothing
你懂的:
main
必须具有IO ()
类型,因为这是编译器强加的要求; f
必须具有类型(Show t) => Maybe t -> IO ()
,因为这是它的类型注释。 Nothing
必须有类型Maybe a
,其中, a = t
(相同t
如在使用f
); a
必须是Show
实例。 但是,这还不足以使程序得以编译,Haskell必须在您的main
动作中对f
的调用进行单态化 ,即找出在f
特定用法中每个类型变量的具体类型。 在这种情况下,这是因为main :: IO ()
类型是单态的(其中没有类型变量),因此在其定义中出现的所有表达式都不能具有未实例化的类型变量。
这就是模棱两可的类型错误的含义:您的程序没有足够的信息供编译器确定对f
的调用的Maybe
参数的元素类型。 可以确定的是它必须是Show
实例,但这还不足以使程序可以编译。
解决方案是在某个位置添加类型注释,以便为其选择具体类型。 有很多方法:
main = f (Nothing :: Maybe Int)
main = f argument
where argument :: Maybe Integer
argument = Nothing
main = (f :: Maybe String -> IO ()) Nothing
之所以只有一种方式,是因为类型推断就像侦探一样,它通过汇集许多不同的线索而起作用,因此,您可以提供许多不同的提示,以使其“解决问题”。 ”
这里Nothing
任何可能的Maybe a
,你必须指定a
你的意思是-尝试
main :: IO ()
main = f (Nothing :: Maybe Int)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.