使用haskell read和TypeClass-类型变量不明确错误

使用haskell read和TypeClass-类型变量不明确错误,haskell,instance,typeclass,Haskell,Instance,Typeclass,我在下面的“试验”定义中有一个不明确的类型变量错误,我想知道是否有什么方法可以使这种情况发生?我只想处理实例,而不是显式的数据类型(比如下面包含的MO1、MO2) 提前谢谢大家!但我担心我可能需要使用一个助手函数,将旧ADT转换为“最新版本…” 西蒙 编辑要澄清这一点,请设想我首先显示一个文件,然后重新加载该对象。那么我的函数更像 trial :: String -> Int trial s = beta x where x = readMe s 之所以会出现错误,是因为编译器不知道

我在下面的“试验”定义中有一个不明确的类型变量错误,我想知道是否有什么方法可以使这种情况发生?我只想处理实例,而不是显式的数据类型(比如下面包含的MO1、MO2)

提前谢谢大家!但我担心我可能需要使用一个助手函数,将旧ADT转换为“最新版本…”

西蒙

编辑要澄清这一点,请设想我首先显示一个文件,然后重新加载该对象。那么我的函数更像

trial :: String -> Int
trial s = beta x
  where x = readMe s

之所以会出现错误,是因为编译器不知道
readMe
应该返回什么具体类型,因为
test
要求它是
MyObj
的实例。它可以是
MO1
MO2
,或者完全其他的东西,
readMe
可以返回其中任何一个

假设您想要
自述文件。showMe
要像
id
一样操作并输出与输入相同的类型,快速而肮脏的方法是定义一个函数,并为其提供一个与输入和输出类型相等的类型签名:

trial :: MyObj a => a -> String
trial = test . readShowMe
    where readShowMe :: MyObj a => a -> a
          readShowMe = readMe . showMe

现在,编译器可以计算出将什么具体类型作为输入提供给
test

之所以会出现错误,是因为编译器不知道
readMe
应该返回什么具体类型,因为
test
只需要它是
MyObj
的一个实例。它可以是
MO1
MO2
,或者完全其他的东西,
readMe
可以返回其中任何一个

假设您想要
自述文件。showMe
要像
id
一样操作并输出与输入相同的类型,快速而肮脏的方法是定义一个函数,并为其提供一个与输入和输出类型相等的类型签名:

trial :: MyObj a => a -> String
trial = test . readShowMe
    where readShowMe :: MyObj a => a -> a
          readShowMe = readMe . showMe

现在,编译器可以确定将什么具体类型作为输入提供给
test

您无法从运行时文件中读取编译时类型。您应该显式地实现运行时类型可变值

例如:

data AnyMyObj = forall a . MyObj a => AnyMyObj a

test :: AnyMyObj -> String
test (AnyMyObj x) = alpha x

showMe :: AnyMyObj -> String
showMe (AnyMyObj x) = show x

readMe :: String -> AnyMyObj
readMe s = AnyMyObj (read s :: MO1) -- maybe something more complicated

trial :: AnyMyObj -> String
trial = test . readMe . showMe

无法从运行时文件中读取编译时类型。您应该显式地实现运行时类型可变值

例如:

data AnyMyObj = forall a . MyObj a => AnyMyObj a

test :: AnyMyObj -> String
test (AnyMyObj x) = alpha x

showMe :: AnyMyObj -> String
showMe (AnyMyObj x) = show x

readMe :: String -> AnyMyObj
readMe s = AnyMyObj (read s :: MO1) -- maybe something more complicated

trial :: AnyMyObj -> String
trial = test . readMe . showMe

这其中有一些奇特的技巧,最终的答案确实是读懂某种存在主义。关于一种非常强大/通用的方法的精妙阐述,请参见Oleg的无标记打印最终课堂讲稿:

但对于像你这样的例子来说,这是一个严重的过激行为——当你有树结构时,特别是当你有表示lambda项的树结构时,通常会出现欺骗

出于您的目的,上面的ony示例大致正确

但是请记住,即使您可以创建MyObj的新实例,您的read函数也只能读取一个固定的宇宙,至少在没有高级黑客的情况下

因此,在这种情况下,我想问您是希望一个typeclass开始,还是希望一个ADT中有更多的构造函数

data MyObj = MO1 { a1 :: String, b1 :: Int }
           | MO2 { a2 :: String, b2 :: Int } deriving (Show,Read)

。。。例如。

这其中有一些奇特的技巧,最终的答案确实是读懂某种存在论。关于一种非常强大/通用的方法的精妙阐述,请参见Oleg的无标记打印最终课堂讲稿:

但对于像你这样的例子来说,这是一个严重的过激行为——当你有树结构时,特别是当你有表示lambda项的树结构时,通常会出现欺骗

出于您的目的,上面的ony示例大致正确

但是请记住,即使您可以创建MyObj的新实例,您的read函数也只能读取一个固定的宇宙,至少在没有高级黑客的情况下

因此,在这种情况下,我想问您是希望一个typeclass开始,还是希望一个ADT中有更多的构造函数

data MyObj = MO1 { a1 :: String, b1 :: Int }
           | MO2 { a2 :: String, b2 :: Int } deriving (Show,Read)

。。。例如。

啊,当例子出错时,你难道不喜欢它吗?请查看原始帖子以获得澄清!:)虽然我仍然相信你的观点,但你的第一部分评论仍然是问题所在。令人遗憾的是,给定typeclass信息和字符串格式,运行时无法确定obj是MO1等等……啊,当示例出错时,你难道不喜欢它吗,请查看原始帖子以获得澄清!:)虽然我仍然相信你的观点,但你的第一部分评论仍然是问题所在。遗憾的是,给定了typeclass信息和字符串格式,运行时无法确定obj是MO1等等……再加上一点类型foo,就得到了一些应该可以工作的东西。谢谢再加上一点foo类型,就得到了一些应该有用的东西。谢谢