Создание монад в haskell

Если бы это должно проанализировать командные строки, я предложил бы использовать палата общин Cli .

библиотека Apache Commons CLI обеспечивает API для обработки интерфейсов командной строки.

10
задан qba 22 November 2009 в 19:49
поделиться

3 ответа

О return :

Prelude> :t return
return :: (Monad m) => a -> m a 

Итак, return принимает аргумент типа ] a и возвращает что-то типа ma . В этом случае m равно LeafConType , поэтому возвращается LeafConType a .

Теперь предположим, что мы передаем True . Тогда a = Bool , поэтому тип возврата должен быть LeafConType Bool . Однако вы определяете:

return = LeafCon

Итак, return True становится LeafCon True . Но это недопустимо, поскольку в определении типа LeafConType указано, что

data LeafConType a = LeafCon (a, Int, Int)

So для LeafConType Bool аргумент LeafCon должен иметь тип ( Bool, Int, Int) , не только Bool . И вот что означает ошибка компиляции: a не может быть таким же, как (a, Int, Int) . Вы заявляете:

Я хочу провести вычисления, пока i ниже, чем n .

Это означает, что вам потребуются некоторые значения по умолчанию для i и n , поскольку в противном случае невозможно будет определить return . Если оба они по умолчанию равны нулю, вы можете определить:

return a = LeafCon (a, 0, 0)

About (>> =) :

Prelude> :t (>>=)
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b

Теперь посмотрите на свою реализацию (немного другая запись, та же идея):

lc@(LeafCon (t, i, n)) >>= f | i >= n    = lc 
                             | otherwise = f t

Здесь мы видим, что lc возвращается, когда i> = n . Но lc имеет тип LeafConType a , а f - это функция, которая может возвращать значение типа LeafConType b , для любое b . В результате может оказаться, что b не равно a , и, следовательно, эти типы не совпадают. В заключение вы серьезно должны задать себе один вопрос:

Можно ли все равно выразить этот тип вычислений в виде монады?

12
ответ дан 3 December 2019 в 17:59
поделиться

Функции, которые вы указали для >> = и return не удовлетворяют типы, требуемые Monad :

return :: a -> LeafConType a

Учитывая объявление

return = LeafCon

, вы присваиваете функции несовместимый тип

return :: (a, Int, Int) -> LeafConType a

Оператор типа return 42 поэтому было бы невозможно в вашей монаде.

Я вообще не понимаю, что ваша монада должна делать. Сначала взгляните на простые рабочие монады!

instance Monad [] where
    (>>=) = concatMap
    return a = [a]

instance Monad Maybe where
    return = Just
    (Just x) >>= f = f x
    Nothing >>= f = Nothing
7
ответ дан 3 December 2019 в 17:59
поделиться

Судя по вашему описанию того, что вы хотите, чтобы ваша монада делала, я думаю, вам нужно что-то вроде этого:

data LeafConType a = LeafCon { runLeafCon' :: Int -> Int -> (Maybe a, Int, Int) }

runLeafCon :: Int -> Int -> LeafConType a -> Maybe a
runLeafCon i n lc = let (t, _, _) = runLeafCon' lc i n in t

getI :: LeafConType Int
getI = LeafCon $ \i n -> (Just i, i, n)

getN :: LeafConType Int
getN = LeafCon $ \i n -> (Just n, i, n)

setI :: Int -> LeafConType ()
setI i = LeafCon $ \_ n -> (Just (), i, n)

setN :: Int -> LeafConType ()
setN n = LeafCon $ \i _ -> (Just (), i, n)

instance Monad LeafConType where
    return t = LeafCon $ \i n -> if (i < n) 
                                 then (Just t, i, n) 
                                 else (Nothing, i, n)

    (LeafCon k) >>= f = 
        LeafCon $ \i n -> 
            let (t, i', n') = k i n
            in case t of
                 Nothing -> (Nothing, i', n')
                 (Just t') -> if (i' < n')
                              then runLeafCon' (f t') i' n'
                              else (Nothing, i, n)


example :: Int -> LeafConType ((), Int)
example x = do 
  i <- getI
  m <- setI (i + x)
  return (m, i + x)

Некоторые примеры:

*Main> runLeafCon 2 10 $ example 4
Just ((),6)
*Main> runLeafCon 2 10 $ example 8
Nothing
*Main> runLeafCon 2 10 $ example 7
Just ((),9)

Я довольно быстро собрал это вместе, это довольно уродливо, и я не проверял, подчиняется ли он какому-либо закону Монад, так что используйте на свой страх и риск! :)

3
ответ дан 3 December 2019 в 17:59
поделиться
Другие вопросы по тегам:

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