Вопрос по Haskell
От: Shmj Ниоткуда  
Дата: 03.09.19 04:45
Оценка:
Как там правильно узнавать ответ... В профильном не ответят, а вот если сказать типа:

  Скрытый текст
ну что за дерьмо-язык, кто только придумать такое мог, 3 дня мучаюсь с простейшей фигней.


— то сразу покажут что был не прав и приведут правильное решение

В общем, решил познать суть Дао сделать свою первую монаду на Haskell. Начать с простого — сделать аналог Maybe, но назвать Maybe2.

По идее вот так:

instance Monad Maybe2 where  
    return x = Just2 x  
    Nothing2 >>= f = Nothing2  
    Just2 x >>= f  = f x  
    fail _ = Nothing2


Т.е. аналог оригинальной, но добавлено 2 (в т.ч. Just2 и Nothing2).

Что дальше? Определить тип Maybe2?

Определил такое:

data Maybe2 a = Nothing2 | Just2 a


Требует чтобы было Applicative.

Пробовал это:

  Скрытый текст
instance Applicative Maybe2 where  
    pure = Just2  
    Nothing2 <*> _ = Nothing2
    (Just2 f) <*> something = fmap f something


— не проканало.

В общем, как сделать полный аналог Maybe?
---
Актуальная база RSDN + Janus
Автор: Shmj
Дата: 15.04 16:31
Re: Вопрос по Haskell
От: CreatorCray  
Дата: 03.09.19 04:49
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Как там правильно узнавать ответ... В профильном не ответят, а вот если сказать типа:


"Это форум аниме?..." (тм)
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re: Вопрос по Haskell
От: Буравчик Россия  
Дата: 03.09.19 05:07
Оценка: 2 (1)
Здравствуйте, Shmj, Вы писали:

S>
S>instance Monad Maybe2 where  
S>    return x = Just2 x  
S>    Nothing2 >>= f = Nothing2  
S>    Just2 x >>= f  = f x  
S>    fail _ = Nothing2
S>


S>В общем, как сделать полный аналог Maybe?


Операция >>= должна возвращать монаду, у тебя нет:

Just2 x >>= f  = f x


Ты вернул некоторое значение f(x), а нужно было вернуть монаду, в которую завернуто f(x)

Правильно будет так:
Just2 x >>= f  = Just2 (f x)


Касательно fmap. Для того, чтобы работало fmap тебе нужно твою монаду сделать функтором (instance Functor Maybe2). Т.е. "реализовать интерфейс" Functor, в котором описана эта функция fmap. До этого времени fmap для Just2 не определена.
Best regards, Буравчик
Re[2]: Вопрос по Haskell
От: Shmj Ниоткуда  
Дата: 03.09.19 06:15
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Правильно будет так:

Б>
Б>Just2 x >>= f  = Just2 (f x)
Б>


Это я не сам придумал — взял готовый пример отсюда: http://learnyouahaskell.com/a-fistful-of-monads#getting-our-feet-wet-with-maybe

Так что не вводите в заблуждение.

Вопрос — каков полный код, чтобы этот пример заработал. Ваше предположение — естественно, ошибочное.

Обычно так и изучаю непонятное — беру 100% рабочий самый простой пример, пытаюсь анализировать. Вношу изменения.

Пока рабочего примера нет
---
Актуальная база RSDN + Janus
Автор: Shmj
Дата: 15.04 16:31
Отредактировано 03.09.2019 6:44 Shmj . Предыдущая версия .
Re: Вопрос по Haskell
От: maxkar  
Дата: 03.09.19 07:46
Оценка: 5 (2) +1
Здравствуйте, Shmj, Вы писали:

S>В общем, как сделать полный аналог Maybe?


Functor ей еще определите, он нужен для Applicative. Остальной код верен и после добавления функтора компилируется. Про необходимость функтора написано в документации http://hackage.haskell.org/package/base-4.12.0.0/docs/Control-Applicative.html

class Functor f => Applicative f where


Вообще по монадам. После объявления типа стандартный порядок объявления — Functor, Applicative, Monad. Они друг на друге строятся.
Re[2]: Вопрос по Haskell
От: D. Mon Великобритания http://thedeemon.livejournal.com
Дата: 03.09.19 09:12
Оценка: 2 (1)
Здравствуйте, Буравчик, Вы писали:

Б>Ты вернул некоторое значение f(x), а нужно было вернуть монаду, в которую завернуто f(x)


f уже и так заворачивает, не надо еще раз.
Re[3]: Вопрос по Haskell
От: Буравчик Россия  
Дата: 03.09.19 14:16
Оценка: 2 (1)
Здравствуйте, Shmj, Вы писали:

S>Так что не вводите в заблуждение.


Да, затупил, с утра пораньше. В реализации операции >>= нет ошибки.
Но, как уже сказали, для Monad нужен Applicative, а для него, в свою очередь, нужен Functor

S>Пока рабочего примера нет


Итого, полный код таков:
data Maybe2 a = Just2 a | Nothing2

instance Functor Maybe2  where
    fmap _ Nothing2       = Nothing2
    fmap f (Just2 a)      = Just2 (f a)

instance Applicative Maybe2 where
    pure = Just2

    Just2 f  <*> m       = fmap f m
    Nothing2 <*> _m      = Nothing2

    Just2 _m1 *> m2      = m2
    Nothing2  *> _m2     = Nothing2

instance Monad Maybe2 where  
    return x = Just2 x  
    Nothing2 >>= f = Nothing2  
    Just2 x >>= f  = f x  
    fail _ = Nothing2
Best regards, Буравчик
Отредактировано 03.09.2019 14:17 Буравчик . Предыдущая версия .
Re[4]: Вопрос по Haskell
От: Shmj Ниоткуда  
Дата: 04.09.19 05:25
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>Итого, полный код таков:


Спасибо , решил чуть усложнить — определить и свои классы.

Начинаю с функтора:

class Functor2 f where  
    fmap2 :: (a -> b) -> f a -> f b


Пробую юзать fmap2 как fmap.

Делаю:

f a = a + 1
fmap f [1,2,3] - ОК
fmap2 f [1,2,3] - Ошибка Could not deduce (Functor2 []) arising from a use of `fmap2' from the context: Num b


Чего не хватает?
---
Актуальная база RSDN + Janus
Автор: Shmj
Дата: 15.04 16:31
Re[5]: Вопрос по Haskell
От: Буравчик Россия  
Дата: 04.09.19 07:05
Оценка: 2 (1)
Здравствуйте, Shmj, Вы писали:

S>Чего не хватает?


Твой функтор не умеет работать со списками. Не хватает:

instance Functor2 [] where 
  fmap2 = map
Best regards, Буравчик
Re[6]: Вопрос по Haskell
От: Shmj Ниоткуда  
Дата: 04.09.19 08:22
Оценка: +1
Здравствуйте, Буравчик, Вы писали:

Б>Твой функтор не умеет работать со списками. Не хватает:


Б>
Б>instance Functor2 [] where 
Б>  fmap2 = map
Б>


Ясно, более-менее начинает прояснятся. Т.е. можно рассматривать как просто один из шаблонов проектирования + красивый синтаксис благодаря поддержке этих фишек на уровне языка.
---
Актуальная база RSDN + Janus
Автор: Shmj
Дата: 15.04 16:31
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.