【发布时间】:2014-07-12 02:02:55
【问题描述】:
我想知道是否可以在 Haskell 中显式实例化/专门化多态函数?我的意思是,想象一下我有如下函数:
parseFile :: FromJSON a => FilePath -> IO Either String a
它尝试解析文件内容的结构取决于a 的类型。现在,我知道可以通过注解指定a:
parseFile myPath :: IO Either String MyType
我想知道是否可以更明确地专门化parseFile,例如使用(specialise parseFile MyType) 将其转换为parseFile :: FilePath -> IO Either String MyType
我问的原因是注解的方法在使用更大的功能时会变得笨拙。例如,假设parseFile 被foo 调用,而bar 又被bar 调用,而bar 的返回值具有类似
:: FromJSON a => IO (([Int],String), (Int, String, Int), a, (Double, [String]))
这意味着如果我想用a 调用bar 作为MyType,我必须用
:: IO (([Int],String), (Int, String, Int), MyType, (Double, [String]))
如果我想多次调用 bar 来处理不同的类型,我最终会多次编写这个注解,这似乎是不必要的重复。
res1 <- bar inputA :: IO (([Int],String), (Int, String, Int), MyType, (Double, [String]))
res2 <- bar inputB :: IO (([Int],String), (Int, String, Int), OtherType, (Double, [String]))
res3 <- bar inputC :: IO (([Int],String), (Int, String, Int), YetAnotherType, (Double, [String]))
有没有办法避免这种情况?我知道可以绑定bar inputA 的结果并在需要MyType 的函数中使用它,从而允许类型引擎推断有问题的a 是MyType 而无需显式注释.然而,这似乎牺牲了类型安全,就好像我不小心在一个需要 MyType 的函数中使用了上述 bar inputB(一个 OtherType)的结果,例如,类型系统不会抱怨,而是当尝试将inputB 解析为MyType 时,程序会在运行时失败,因为inputB 包含OtherType,而不是MyType。
【问题讨论】:
标签: haskell polymorphism