Dan*_*rro 4 haskell type-families
我想知道是否有任何方法(可能使用Type Families)Buildable使用build方法定义类型类,以便这样的东西可以工作:
>>> import qualified Data.ByteString.Builder as B (Builder)
>>> import qualified Data.Text.Lazy.Builder as T (Builder)
>>> -- This should internally use `int8` from `Data.ByteString.Builder`:
>>> build (8::Int8) :: B.Builder
>>> -- This should internally use `decimal` from `Data.Text.Lazy.Builder`:
>>> build (8::Int8) :: T.Builder
>>> -- If no concrete type is specified, I'd expect something like this:
>>> :t build (8::Int8)
GBuilder Int8
Run Code Online (Sandbox Code Playgroud)
我知道如何使它与MPTC一起工作,但我必须明确定义要构建的值的类型和构建器的类型.有没有办法让类型系统自动选择预期的类型而不显式传递它?
嗯,明显的解决方案如下:
class Builder b where
type Element b
build :: Element b -> b
instance Builder B.Builder where
type Element B.Builder = Int8
build = B.int8
instance Builder T.Builder where
type Element T.Builder = Int8
build = T.decimal
Run Code Online (Sandbox Code Playgroud)
但是,这个问题是类型族不能用于确定实例.所以在这种情况下,实例只能由bfrom 确定build :: Element b -> b,而不能由from 确定Element b.在处理类型检查错误时,这很有用.
由于我刚才提到的很多情况,只能使用数据系列.标准方法是提供newtype包装器.例如:
class Builder b where
data Element b
build :: Element b -> b
instance Builder B.Builder where
newtype Element B.Builder = BElement Int8
build (BElement a) = B.int8 a
Run Code Online (Sandbox Code Playgroud)
在这种情况下,实例可以从两个来确定b和Element b的build :: Element b -> b.