动态数据作为Haskell函数的输入

时间:2013-12-23 21:57:29

标签: haskell

我希望获得一个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

,其中sayHellox为实例的类的函数。

2 个答案:

答案 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"