将具有有效功能空间(如 ML)的语言核心嵌入到 Haskell 中有多实用?
Posted
技术标签:
【中文标题】将具有有效功能空间(如 ML)的语言核心嵌入到 Haskell 中有多实用?【英文标题】:How practical is it to embed the core of a language with an effectful function space (like ML) into Haskell? 【发布时间】:2011-03-25 08:35:53 【问题描述】:正如 Moggi 20 年前提出的那样,ML 等语言的有效函数空间 ->
可以分解为标准的总函数空间 =>
加上一个强 monad T
来捕捉效果。
A -> B
分解为 A => (T B)
现在,Haskell 支持 monad,包括一个 IO monad,它看起来足以满足 ML 中的效果,它有一个包含 => 的函数空间(但也包括部分函数)。因此,我们应该能够通过这种分解将 ML 的相当一部分片段转换为 Haskell。理论上我认为这是可行的。
我的问题是这样的嵌入是否可行:是否有可能设计一个 Haskell 库,允许在 Haskell 中以与 ML 相距不远的风格进行编程?如果是这样,性能如何?
我对“实用”的标准是,现有的具有广泛使用效果的 ML 代码可以通过嵌入相对容易地转录成 Haskell,包括涉及高阶函数的复杂案例。
为了具体说明,下面是我自己尝试通过嵌入进行的这种转录。主要功能是一些简单的 ML 代码的转录,这些代码命令式地生成 5 个不同的变量名称。我的版本不是直接使用分解,而是提升函数以便它们评估它们的参数 - main
之前的定义是一个包含提升原语的迷你库。这行得通,但有些方面并不完全令人满意。
-
通过
val
将值注入到计算中的语法噪音有点过大。拥有未提升的函数版本(如 rdV
)会对此有所帮助,但代价是需要定义这些函数。
像varNum
这样的非值定义需要通过<-
在do
中进行一元绑定。然后,这会强制依赖于它们的任何定义也位于同一 do
表达式中。
看来整个程序最终可能会出现在一个巨大的do
表达式中。这就是机器学习程序经常被考虑的方式,但在 Haskell 中它并没有得到很好的支持 - 例如,你不得不使用 case
而不是方程式。
我想尽管贯穿整个 IO monad,还是会有一些懒惰。鉴于 ML 程序将被设计用于严格评估,因此可能应该消除惰性。不过,我不确定最好的方法是什么。
那么,对于改进这一点,或者关于使用相同分解的更好方法,或者甚至完全不同的方法来使用反映 ML 的风格在 Haskell 中实现相同的广泛编程目标有什么建议吗? (并不是我不喜欢 Haskell 的风格,只是我希望能够轻松地映射现有的 ML 代码。)
import Data.IORef
import Control.Monad
val :: Monad m => a -> m a
val = return
ref = join . liftM newIORef
rdV = readIORef -- Unlifted, hence takes a value
(!=) r x = do rr <- r; xx <- x; writeIORef rr xx
(.+),(.-) :: IO Int -> IO Int -> IO Int
( (.+),(.-) ) = ( liftM2(+), liftM2(-) )
(.:) :: IO a -> IO [a] -> IO [a]
(.:) = liftM2(:)
showIO :: Show a => IO a -> IO String
showIO = liftM show
main = do
varNum <- ref (val 0)
let newVar = (=<<) $ \() -> val varNum != (rdV varNum .+ val 1) >>
val 'v' .: (showIO (rdV varNum))
let gen = (=<<) $ \n -> case n of 0 -> return []
nn -> (newVar $ val ()) .: (gen (val n .- val 1))
gen (val 5)
【问题讨论】:
+1 提出了一个我不够聪明,无法做出贡献的问题 鉴于您发布的问题和答案的性质,如果您还没有考虑adding your support here,您会考虑吗? @camccann 有趣 - 我想我一直在测试并发现 Stack Overflow 对此类问题很有用(这个问题可能会突破极限,或者只是难以回答)。我在 TCS 网站上有些分歧:我通常不喜欢将理论与实践分开,也不喜欢“理论”一词。这个问题与单子有关,但我主要是问一些实际用途的东西。就我个人而言,我可能对 SO 上的 TCS 标签更满意。一般来说,当没有明确的分界线时,我认为将事物集中在一起然后通过标签投影出子集是一个更好的模型。 可能感兴趣:***.com/questions/28139259. 【参考方案1】:Here 是一种可能的方式,通过 sigfpe。它不包括 lambda,但似乎可以扩展到它们。
【讨论】:
我可能会尝试使用一些有趣的技术。这与我给出的代码中的想法相似(因为 Andrzej Filinski 和我一起在 CMU 学习,这并不奇怪)。此外,我会将嵌入归类为“理论上的作品”而不是“实践中的作品”。另外,我想我现在想避免使用模板,看看在不破解语法的情况下有哪些不错的嵌入是可能的。以上是关于将具有有效功能空间(如 ML)的语言核心嵌入到 Haskell 中有多实用?的主要内容,如果未能解决你的问题,请参考以下文章
论文泛读176具有各向同性和等距条件的跨语言 BERT 上下文嵌入空间映射