Re[51]: Есть ли вещи, которые вы прницпиально не понимаете...
От: Klapaucius  
Дата: 14.01.14 11:35
Оценка: 68 (1)
Здравствуйте, Sinclair, Вы писали:

S>Интересно. А при этом с "обычными", немонадными a и b такая запись работает? Ну, то есть можно ли вообще всегда описывать функции в do-нотации, чтобы они работали с произвольными монадами?


Чтоб такой код работал с обычными значениями, их придется обернуть в монаду Identity:

-- код был с ошибкой, правильно его записать так:

foo a b = do x <- a
             y <- b
             return $ x + y

-- или, что то же самое, но идиоматичнее:

foo = liftM2 (+)

-- теперь
runIdentity $ foo (Identity 2) (Identity 40)
-- получаем:
42

Это вполне применяется на практике, к примеру, все операции в пакете vector (это хаскельная библиотека для работы с массивами) монадические, а специализированная, нелифтнутые версии реализуются через монадические, вроде:

map f = mapM (return . f)


Lifted operators в хаскеле вполне реализуются:

{-# LANGUAGE FlexibleInstances, OverlappingInstances #-}

import Control.Applicative

instance (Applicative f, Num n) => Num (f n) where
    (+) = liftA2 (+)
    (-) = liftA2 (-)
    (*) = liftA2 (*)
    abs = fmap abs
    signum = fmap signum
    fromInteger = pure . fromIntegral

instance (Applicative f, Fractional n) => Fractional (f n) where
    (/) = liftA2 (/)
    recip = fmap recip
    fromRational = pure . fromRational

Все, теперь у нас арифметика лифтнута в любой аппликативный функтор и мы можем писать на языке j:

>>> 2 + 7 * 8
58
>>> Just 2 + Just 7 * Just 8
Just 58
>>> Just 2 + Nothing * Just 8
Nothing
>>> [1..3] + [7..9] * [11,12]
[78,85,89,97,100,109,79,86,90,98,101,110,80,87,91,99,102,111]
>>> getZipList $ ZipList[1..3] + ZipList[7..9] * ZipList[11..13]
[78,98,120]
-- функции - это тоже функторы и монады:
>>> sum / (fromIntegral . length) $ [1..3] -- вычисляем среднее значение: делим сумму на длину
2.0


Вообще, нормальная работа с функторами/монадами в хаскеле возможна, в основном, не благодаря спецсинтаксису (который как раз страшноватый), а благодаря приличным возможностям для написания полиморфного кода и комбинирования комбинаторов
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.