J. *_*son 6 dsl haskell typeclass lifting
我想将Haskell函数提升为更高阶的lambda演算编码.这几乎是从Oleg的Typed Tagless Final编码中逐字逐句的.
class Lam r where
emb :: a -> r a
(^) :: r (r a -> r a) -> (r a -> r a)
lam :: (r a -> r a) -> r (r a -> r a)
instance Lam Identity where
emb = Identity
f ^ x = f >>= ($ x)
lam f = return (f . return =<<) -- call-by-value
eval = runIdentity
Run Code Online (Sandbox Code Playgroud)
我可以将任意Haskell类型嵌入到Lam使用中emb,但我不能(^)用于应用程序.此外,提升的功能会表现得很懒散.相反,我必须通过应用程序解除它们的应用程序.
emb1 :: ( Applicative r, Lam r )
=> (a -> b) -> r (r a -> r b)
emb1 f = lam $ \ra -> f <$> ra
emb2 :: ( Applicative r, Lam r )
=> (a -> b -> c) -> r (r a -> r (r b -> r c))
emb2 f = lam $ \ra -> lam $ \rb -> f <$> ra <*> rb
emb3 :: ( Applicative r, Lam r )
=> (a -> b -> c -> d)
-> r (r a -> r (r b -> r (r c -> r d)))
emb3 f = lam $ \ra -> lam $ \rb -> lam $ \rc -> f <$> ra <*> rb <*> rc
>>> eval $ emb2 (+) ^ emb 1 ^ emb 2
3
Run Code Online (Sandbox Code Playgroud)
不过,那是很多样板.我想创建一个适用于任何arity函数的通用提升函数.我觉得它会使用一个类似于有可能Printf的PrintfType或fixed-vector的Cont类型.我可以使用类型函数指定我想要的内容
type family Low h o
type instance Low () o = o
type instance Low (a, h) o = a -> Low h o
type family Lift r h o
type instance Lift r () o = o
type instance Lift r (a, h) o = r a -> r (Lift r h o)
class Emb r h o where
embed :: Low h o -> r (Lift r h o)
instance ( Lam r ) => Emb r () o where
embed = emb
instance ( Lam r, Applicative r, Emb r h o ) => Emb r (a, h) o where
embed = ?
Run Code Online (Sandbox Code Playgroud)
但是我通过这种方法非常困难,通常是由于注入性问题.我能够通过新类型包装器和范围类型变量的真正可怕组合来解决注入性,但它实际上从未进行过类型检查.
这有可能在Haskell中表达吗?
您可能想看看
tagless-final 风格中的普通和一次性 CPS 转换。诀窍是用对象语言概括 Arrow 类型。事实上,我们经常将 Haskell 的类型构造函数->用于对象语言中的函数类型(要嵌入),这是巧合和方便。一般来说,对象函数不会简单地映射到 Haskell 函数。引用文章中的代码包含 ESymantics
-- How to interpret arrows and other types
type family Arr (repr :: * -> *) (a :: *) (b :: *) :: *
class ESymantics repr where
int :: Int -> repr Int
add :: repr Int -> repr Int -> repr Int
lam :: (repr a -> repr b) -> repr (Arr repr a b)
app :: repr (Arr repr a b) -> repr a -> repr b
Run Code Online (Sandbox Code Playgroud)
现在我们有足够的自由来根据特定的代表来解释 Arr。引用的文章将 Arr 解释为 CPS 实例。
编辑:事实证明,我们可以实现相同的效果 - 重新定义对象语言的箭头含义 - 无需引入 Arr 类型(及其单射性问题)并且无需 ESemantics。上面的普通和一次性 CPS 转换链接显示了新代码,使用标准语义并重新解释了函数类型构造函数的含义。不再有任何单射性问题。
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |