Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell Can';t正确定义通用类型的转换,即用GADT定义的转换_Haskell_Ghc_Gadt - Fatal编程技术网

Haskell Can';t正确定义通用类型的转换,即用GADT定义的转换

Haskell Can';t正确定义通用类型的转换,即用GADT定义的转换,haskell,ghc,gadt,Haskell,Ghc,Gadt,我已经定义了一个可以包含任何内容的通用数据类型(好吧,在当前的实现中不是完全包含任何内容) 这是(完整代码): 我可以在控制台中使用它: *Main> a [Any "Hahaha",Any 123] it :: [AnyT] *Main> readAnyT (read::String->Float) "134" Any 134.0 it :: AnyT *Main> showAnyT $ Any 125 "125" it :: String 嗯,我有,但我需要以某种

我已经定义了一个可以包含任何内容的通用数据类型(好吧,在当前的实现中不是完全包含任何内容)

这是(完整代码):

我可以在控制台中使用它:

*Main> a
[Any "Hahaha",Any 123]
it :: [AnyT]
*Main> readAnyT (read::String->Float) "134"
Any 134.0
it :: AnyT
*Main> showAnyT $ Any 125
"125"
it :: String

嗯,我有,但我需要以某种方式处理它。例如,让我们定义转换函数(函数定义,添加到前面的代码):

这就是问题所在!以前代码中任何定义的不正确!我也不知道该怎么纠正。我在GHCi中得到错误:

2.hs:18:23:
    Could not deduce (a ~ a1)
    from the context (Show a1, Read a1)
      bound by a pattern with constructor
                 Any :: forall a. (Show a, Read a) => a -> AnyT,
               in an equation for `fromAny'
      at 2.hs:18:10-18
      `a' is a rigid type variable bound by
          the type signature for fromAny :: AnyT -> a at 2.hs:17:12
      `a1' is a rigid type variable bound by
           a pattern with constructor
             Any :: forall a. (Show a, Read a) => a -> AnyT,
           in an equation for `fromAny'
           at 2.hs:18:10
    In the expression: thing
    In an equation for `fromAny': fromAny (Any thing) = thing
Failed, modules loaded: none.
我也尝试了一些其他的方法来避免犯错误


我有一个非常糟糕的解决方案:通过showAnyT和read来定义必要的函数(替换以前的函数定义):

是的,这是工作。我可以玩它:

*Main> fromAny $ Any 1352 ::Float
1352.0
it :: Float
*Main> fromAny $ Any 1352 ::Int
1352
it :: Int
*Main> fromAny $ Any "Haha" ::String
"Haha"
it :: String
但我认为这很糟糕,因为它使用字符串进行转换


你能帮我找到一个简洁而好的解决办法吗?

你有的是一种叫做。如果遵循该链接,您将发现在这种模式中,处理容器类型内“数据”的唯一方法是使用类型类

在您当前的示例中,您提到
a
应该有
Read
Show
实例,这意味着只有这些类型类中的函数可以在
a
上使用,其他什么都不能使用,如果您想支持
a
上的一些操作,则应该使用所需的类型对其进行约束班级


你可以这样想:你可以把任何东西放在盒子里。现在,当你从那个盒子里取出一些东西时,你无法指定你将从中得到什么,因为你可以把任何东西放进去。现在,如果你说你可以把任何可以吃的东西放在这个盒子里,那么你肯定当你从这个盒子里挑选东西时,它是可以吃的。如果遵循该链接,您将发现在这种模式中,处理容器类型内“数据”的唯一方法是使用类型类

在您当前的示例中,您提到
a
应该有
Read
Show
实例,这意味着只有这些类型类中的函数可以在
a
上使用,其他什么都不能使用,如果您想支持
a
上的一些操作,则应该使用所需的类型对其进行约束班级


你可以这样想:你可以把任何东西放在盒子里。现在,当你从那个盒子里取出一些东西时,你无法指定你将从中得到什么,因为你可以把任何东西放进去。现在,如果你说你可以把任何可以吃的东西放在这个盒子里,那么你肯定当你从这个盒子里挑选东西时,它是可以吃的。如果遵循该链接,您将发现在这种模式中,处理容器类型内“数据”的唯一方法是使用类型类

在您当前的示例中,您提到
a
应该有
Read
Show
实例,这意味着只有这些类型类中的函数可以在
a
上使用,其他什么都不能使用,如果您想支持
a
上的一些操作,则应该使用所需的类型对其进行约束班级


你可以这样想:你可以把任何东西放在盒子里。现在,当你从那个盒子里取出一些东西时,你无法指定你将从中得到什么,因为你可以把任何东西放进去。现在,如果你说你可以把任何可以吃的东西放在这个盒子里,那么你肯定当你从这个盒子里挑选东西时,它是可以吃的。如果遵循该链接,您将发现在这种模式中,处理容器类型内“数据”的唯一方法是使用类型类

在您当前的示例中,您提到
a
应该有
Read
Show
实例,这意味着只有这些类型类中的函数可以在
a
上使用,其他什么都不能使用,如果您想支持
a
上的一些操作,则应该使用所需的类型对其进行约束班级


你可以这样想:你可以把任何东西放在盒子里。现在,当你从那个盒子里取出一些东西时,你无法指定你将从中得到什么,因为你可以把任何东西放进去。现在,如果您说您可以将任何可吃的东西放在这个框中,那么您可以确定,当您从这个框中选择一些东西时,它将是可吃的。

您正在使用GADT创建一个存在的数据类型。构造函数中存在类型
a
,但无法恢复。唯一可用的信息是它有
Show
Read
实例。确切的类型被忘记了,因为这是构造函数的类型指示类型系统执行的操作。请确保此类型具有正确的实例,然后忘记它是什么

顺便说一句,你错过了一个功能:

readLike :: String -> AnyT -> AnyT
readLike s (Any a) = Any $ read s `asTypeOf` a

在模式匹配的上下文中,编译器知道无论
a
有什么类型,都有一个
Read
实例,它可以应用该实例。即使它不确定
a
是什么类型。但是它所能做的就是显示它,或者读取与它相同类型的字符串。

您正在使用GADT创建一个存在数据类型。构造函数中存在类型
a
,但无法恢复。唯一可用的信息是它有
Show
Read
实例。确切的类型被忘记了,因为这是构造函数的类型指示类型系统执行的操作。请确保此类型具有正确的实例,然后忘记它是什么

顺便说一句,你错过了一个功能:

readLike :: String -> AnyT -> AnyT
readLike s (Any a) = Any $ read s `asTypeOf` a
在模式匹配的上下文中,编译器知道无论
a
有什么类型,都有
读取*Main> fromAny $ Any 1352 ::Float
1352.0
it :: Float
*Main> fromAny $ Any 1352 ::Int
1352
it :: Int
*Main> fromAny $ Any "Haha" ::String
"Haha"
it :: String
readLike :: String -> AnyT -> AnyT
readLike s (Any a) = Any $ read s `asTypeOf` a
import Data.Typeable

data AnyT where
    Any :: (Show a, Read a, Typeable a) => a -> AnyT
readAnyT :: (Read a, Show a, Typeable a) => (String -> a) -> String -> AnyT
readAnyT readFun str = Any $ readFun str

showAnyT :: AnyT -> String
showAnyT (Any thing) = show thing

toAnyT :: (Show a, Read a, Typeable a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny :: Typeable a => AnyT -> Maybe a
fromAny (Any thing) = cast thing