Я совершенно новичок в Хаскеле. Я пытаюсь перегрузить пользовательскую функцию myadd для разных контейнеров. Насколько я понимаю, вы должны делать это через занятия. Вот что я попробовал:

class Addition a where
  myadd :: a -> a -> a

instance Addition Int where
  myadd a b = a + b

instance Addition Maybe where
  myadd (Just a) (Just b) = Just (a + b)

main = do
  let a = 3 :: Int
  let b = 4
  let c = myadd a b
  print c

  let d = (Just a)
  let e = (Just b)
  let f = myadd d e
  print f

Но я получаю следующие ошибки:

test.hs:7:19: error:
    ? Expecting one more argument to ‘Maybe’
      Expected a type, but ‘Maybe’ has kind ‘* -> *’
    ? In the first argument of ‘Addition’, namely ‘Maybe’
      In the instance declaration for ‘Addition Maybe’
3
user3689034 27 Май 2017 в 18:44

2 ответа

Лучший ответ

Addition имеет вид * -> *, поэтому аргумент Addition должен быть вида *. Maybe имеет вид * -> *. Вам необходимо передать дополнительный аргумент типа Maybe, чтобы он имел вид *.

instance Addition (Maybe a)

Проблема в том, что Maybe a не является экземпляром Addition для произвольного a, только для a, которые уже являются экземплярами Addition. Вы можете указать, что a является экземпляром Addition, вот так:

instance Addition a => Addition (Maybe a)

Также ваша реализация должна использовать myadd вместо +:

instance Addition a => Addition (Maybe a) where
   myadd (Just a) (Just b) = Just (myadd a b)
3
Justin Raymond 11 Окт 2018 в 12:32

Один из способов сделать это будет через

instance (Num a) => Addition (Maybe a) where
    myadd (Just x) (Just y) = Just (x + y)       

Обратите внимание на следующее:

  • Maybe a является экземпляром Addition, а не Maybe.
  • Экземпляр ограничен типами a, где Num a.
2
Ami Tavory 27 Май 2017 в 16:14