в haskell, зачем Мне нужно указать ограничения типа, почему компилятор не может их понять?

Рассмотрим функцию,

add a b = a + b

Это работает:

*Main> add 1 2
3

Однако, если я добавлю сигнатуру типа, указывающую, что я хочу добавить объекты того же типа:

add :: a -> a -> a
add a b = a + b

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

test.hs:3:10:
    Could not deduce (Num a) from the context ()
      arising from a use of `+' at test.hs:3:10-14
    Possible fix:
      add (Num a) to the context of the type signature for `add'
    In the expression: a + b
    In the definition of `add': add a b = a + b

Таким образом, GHC явно может сделать вывод, что мне нужен Ограничение типа Num , поскольку оно только что сообщило мне:

add :: Num a => a -> a -> a
add a b = a + b

Работает.

Почему GHC требует от меня добавить ограничение типа? Если я занимаюсь универсальным программированием, почему он не может работать с чем-то, что умеет использовать оператор + ?

В программировании шаблонов C ++ вы можете легко это сделать:

#include <string>
#include <cstdio>

using namespace std;

template<typename T>
T add(T a, T b) { return a + b; }

int main()
{
    printf("%d, %f, %s\n",
           add(1, 2),
           add(1.0, 3.4),
           add(string("foo"), string("bar")).c_str());
    return 0;
}

компилятор определяет типы аргументов add и генерирует версию функции для этого типа. Кажется, есть фундаментальное различие в подходе Haskell, можете ли вы описать его и обсудить компромиссы? Мне кажется, что это было бы решено, если бы GHC просто заполнил для меня ограничение типа, поскольку он, очевидно, решил, что это необходимо. Тем не менее, почему вообще ограничение типа? Почему бы просто не скомпилировать успешно, если функция используется только в допустимом контексте, где аргументы находятся в Num ?

6
задан Micha Wiedenmann 21 April 2017 в 09:21
поделиться