Как практичный это должно встроить ядро языка с effectful функциональным пространством (как ML) в Haskell?

Поскольку Moggi сделал предложение 20 лет назад, effectful функциональное пространство -> из языков как ML может быть разложен на стандартное общее функциональное пространство => плюс сильная монада T получать эффекты.

A -> B разлагается к A => (T B)

Теперь, Haskell поддерживает монады, включая монаду IO, которая кажется достаточной для эффектов в ML, и он имеет функциональное пространство, которое содержит => (но также и включает частичные функции). Так, мы должны смочь перевести значительный фрагмент ML в Haskell через это разложение. В теории я думаю, что это работает.

Мой вопрос состоит в том, может ли встраивание как это быть практичным: действительно ли возможно разработать библиотеку Haskell, которая позволяет программировать в Haskell в стиле, не слишком далеком от ML? И раз так как производительность будет?

Мои критерии "практического" - то, что существующий код ML с широким применением эффектов мог быть относительно легко записан в Haskell через встраивание, включая сложные случаи, включающие функции высшего порядка.

Для создания этого бетона моя собственная попытка такой записи через встраивание ниже. Основная функция является записью некоторого простого кода ML, который обязательно генерирует 5 отличных имен переменной. Вместо того, чтобы использовать разложение непосредственно, мои функции лифтов версии так, чтобы они оценили свои аргументы - определения до main мини-библиотека включая снятые примитивы. Это работает хорошо, но некоторые аспекты не являются полностью удовлетворительными.

  1. Существует немного слишком много синтаксического шума для инжекции значений в вычисления через val. Не сняв версии функций (как rdV) помог бы этому, за счет требования, чтобы они были определены.
  2. Определения незначения как varNum потребуйте одноместной привязки через <- в a do. Это затем вызывает любые определения, которые зависят от них, чтобы также быть в том же do выражение.
  3. Кажется затем, что целая программа могла бы закончить тем, что находилась в одном огромном do выражение. Это - то, как программы ML часто рассматривают, но в Haskell это не совсем также поддерживало - например, Вы вынуждены использовать case вместо уравнений.
  4. Я предполагаю, что будет некоторая лень несмотря на поточную обработку монады IO повсюду. Учитывая, что программа ML была бы разработана для строгой оценки, лень должна, вероятно, быть удалена. Я не уверен, каково лучший способ сделать это все же.

Так, совет относительно улучшения этого, или относительно лучших подходов с помощью того же разложения или даже очень отличающихся способов достигнуть той же широкой цели программирования в 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)
16
задан RD1 5 August 2010 в 01:20
поделиться

1 ответ

Вот возможный способ, предложенный sigfpe. Он не охватывает ламбды, но, похоже, его можно распространить и на них.

3
ответ дан 30 November 2019 в 23:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: