Поскольку Moggi сделал предложение 20 лет назад, effectful функциональное пространство ->
из языков как ML может быть разложен на стандартное общее функциональное пространство =>
плюс сильная монада T
получать эффекты.
A -> B
разлагается к A => (T B)
Теперь, Haskell поддерживает монады, включая монаду IO, которая кажется достаточной для эффектов в ML, и он имеет функциональное пространство, которое содержит => (но также и включает частичные функции). Так, мы должны смочь перевести значительный фрагмент ML в Haskell через это разложение. В теории я думаю, что это работает.
Мой вопрос состоит в том, может ли встраивание как это быть практичным: действительно ли возможно разработать библиотеку Haskell, которая позволяет программировать в Haskell в стиле, не слишком далеком от ML? И раз так как производительность будет?
Мои критерии "практического" - то, что существующий код ML с широким применением эффектов мог быть относительно легко записан в Haskell через встраивание, включая сложные случаи, включающие функции высшего порядка.
Для создания этого бетона моя собственная попытка такой записи через встраивание ниже. Основная функция является записью некоторого простого кода ML, который обязательно генерирует 5 отличных имен переменной. Вместо того, чтобы использовать разложение непосредственно, мои функции лифтов версии так, чтобы они оценили свои аргументы - определения до main
мини-библиотека включая снятые примитивы. Это работает хорошо, но некоторые аспекты не являются полностью удовлетворительными.
val
. Не сняв версии функций (как rdV
) помог бы этому, за счет требования, чтобы они были определены.varNum
потребуйте одноместной привязки через <-
в a do
. Это затем вызывает любые определения, которые зависят от них, чтобы также быть в том же do
выражение.do
выражение. Это - то, как программы ML часто рассматривают, но в Haskell это не совсем также поддерживало - например, Вы вынуждены использовать case
вместо уравнений.Так, совет относительно улучшения этого, или относительно лучших подходов с помощью того же разложения или даже очень отличающихся способов достигнуть той же широкой цели программирования в Haskell, использующем стиль, который зеркально отражает ML? (Не то, чтобы мне не нравится стиль 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)
Вот возможный способ, предложенный sigfpe. Он не охватывает ламбды, но, похоже, его можно распространить и на них.