我希望获得一个Dynamic
数据类型作为函数的输入,并在执行此类函数时使用它。
假设这个功能:
getA :: (Typeable b) => b -> IO ()
getA t = do
let v = case fromDynamic t of
Nothing -> error "Nao Foi Possível Converter"
Just x -> x
putStrLn "Ok"
发生此错误:
Could not deduce (b ~ Dynamic)
from the context (Typeable b)
bound by the type signature for getA :: Typeable b => b -> IO ()
如果我将函数的签名更改为getA :: Dynamic -> IO ()
,则错误为:
No instance for (Typeable a0) arising from a use of `fromDynamic'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
在这种情况下我应该使用哪种数据类型?
此外,是否可以从x
为实例的类调用函数?类似的东西:
case fromDynamic t of
Nothing -> error "Nao Foi Possível Converter"
Just x -> putStrLn$ sayHello x
,其中sayHello
是x
为实例的类的函数。
答案 0 :(得分:6)
getA :: Dynamic -> IO ()
是正确的签名。但你实际上需要使用来做某事!如果您只是匹配Just x -> x
,那么编译器不知道您希望使用此值的类型。
v = case fromDynamic t of
Just x -> x + 5 :: Int
应该有用。
答案 1 :(得分:3)
编译器实际上告诉你到底出了什么问题,在案例匹配表达式中使用“x”是不明确的,因为你的使用“x”是完全多态的,类型检查器不能推断出值,因为它可能是任何东西
例如,如果您想打印提取的值,那么您希望该值为String
,其中putStrLn
语句将见证(x ~ String)
的约束并正确编译
import Data.Typeable
import Data.Dynamic
getA :: Dynamic -> IO ()
getA t = do
case fromDynamic t of
Nothing -> error "Nao Foi Possível Converter"
Just (x :: String) -> putStrLn x
putStrLn "Ok"