我想制作以下类型的可推断:
class Lit a
instance Lit Int
instance Lit Float
class App a b
instance App Float b
f :: (Lit a, App a b) => a -> b -- a should be Float
我知道无法将此示例推断为a
到Float
因为类型类至少没有关闭。
我应该怎样做才能达到目的?
此外,我想要做的是使用TH和Haskell Type Checker构建Typed EDSL。例如,如果变量(Int或Float)“p”乘以Float,我想将“p”推断为Float。因此,对此的解决方案也很受欢迎。
答案 0 :(得分:1)
目前还不是很清楚你要用这段代码解决什么问题,但正如@chi所说,你可以试试FunDeps
{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}
class Lit a
instance Lit Int
instance Lit Float
class App a b | b -> a
instance App Float b
f :: (Lit a, App a b) => a -> Maybe b
f x = Nothing
或TypeFamilies
{-# LANGUAGE TypeFamilies, FlexibleInstances #-}
class Lit a
instance Lit Int
instance Lit Float
class App res where
type Arg res
instance App res where
type Arg res = Float
f :: App b => Arg b -> Maybe b
f x = Nothing
在这个例子中使用FunDeps更简洁,但根据我的经验,TypeFamilies + GADTs解决方案对于类型级编程更直接和易于管理。