【发布时间】:2019-07-02 13:03:22
【问题描述】:
我想定义一个类型类,用于根据类型访问记录中的特定字段。在这个玩具示例中,我们有一个 Failable(这只是一个 Either),它可以出现在不同的记录中并包装不同的类型。我很感兴趣是否可以定义一个函数 failableFrom 并让编译器根据上下文选择正确的实例。
type Money = Double
type Name = String
type ErrMsg = String
class HasFailable a b where
failableFrom :: a -> Either ErrMsg b
data SomeRecord = SomeRecord (Either ErrMsg Name) (Either ErrMsg Money)
instance HasFailable SomeRecord Name where
failableFrom (SomeRecord name _) = name
instance HasFailable SomeRecord Money where
failableFrom (SomeRecord _ money) = money
data SomeOtherRecord = SomeOtherRecord (Either ErrMsg Name)
instance HasFailable SomeOtherRecord Name where
failableFrom (SomeOtherRecord name) = name
data SomeOtherOtherRecord = SomeOtherOtherRecord (Either ErrMsg Money)
instance HasFailable SomeOtherOtherRecord Money where
failableFrom (SomeOtherOtherRecord money) = money
-- some record
record = SomeRecord (Right "John") (Right 200.0)
-- let the compiler decide what failableFrom function to use
moreMoney = fmap (\money -> money + 200.0) $ failableFrom record
我问这个主要是出于对 Haskell 中可能发生的事情的好奇。
【问题讨论】:
-
如果您将最后一个
instance HasFailable SomeOtherOtherRecord Name更改为instance HasFailable SomeOtherOtherRecord Money并确定moreMoney的类型(例如通过执行money + 200 :: Money),则该代码有效。 -
SomeRecord,SomeOtherRecord和SomeOtherOtherRecord都可以是我认为的类型。我认为你正在做的事情太难了。 -
@melpomene 已修复,谢谢。