Так как Донс проделал такую хорошую работу, ответив на ваш вопрос, я буду работать над его вопросом ....
Например, в вашем вопросе, где вы впервые набираете среднее значение по заданному списку, получаете хороший ответ. Затем вы берете то, что похоже на тот же список , присваиваете его переменной, затем используете функцию переменная ..., которая затем взрывается.
Здесь вы столкнулись с настройкой в компиляторе, называемой DMR: D прочитанная M ономорфная R эстракция. Когда вы передали список прямо в функцию, компилятор не сделал предположения о том, каким типом были числа, он просто определил, какие типы могут быть основаны на использовании, а затем выбрал один, когда больше не смог сузить поле. Это похоже на прямую противоположность печати по утке.
В любом случае, когда вы присваиваете список переменной, включается DMR. Так как вы поместили список в переменную, но без подсказок о том, как вы хотите его использовать, DMR заставил компилятор выбрать тип в данном случае он выбрал тот, который соответствовал форме и, казалось, подходил: Integer
. Поскольку ваша функция не может использовать Integer в своей операции /
(ей нужен тип в классе Fractional
), это вызывает нарекания: в классе Fractional
нет экземпляра Integer
. В GHC есть параметры, которые можно настроить, чтобы он не приводил ваши значения в одну форму («мономорфная», получить?) До тех пор, пока это не понадобится, но делает сообщения об ошибках немного сложнее для выяснения.
Теперь, на другой ноте, у вас был ответ на ответ Дона, который привлек мое внимание:
Я был введен в заблуждение диаграммой на последней странице cs.ut.ee/~varmo/MFP2004/PreludeTour.pdf
это показывает, что Floating НЕ наследует свойства от Real, и тогда я предположил, что
у них не будет общих типов.
Haskell делает типы иначе, чем вы привыкли. Real
и Floating
являются классами типов, которые работают больше как интерфейсы, чем классы объектов. Они говорят вам, что вы можете сделать с типом, который находится в этом классе, но это не значит, что какой-то тип не может делать другие вещи, так же как наличие одного интерфейса означает, что класс (n OO-style) не может есть другие.
Изучение Haskell похоже на изучение Calculus
Я бы сказал, что изучение Haskell похоже на изучение шведского языка - есть много маленьких, простых вещей (букв, цифр), которые выглядят и работают одинаково, но есть также слова, которые выглядят так, как будто они означают одно, когда они на самом деле означает что-то еще. Но как только вы начнете бегло в этом разбираться, ваши обычные друзья будут удивлены тем, как вы можете извергать эти странные вещи, которые заставляют великолепных красавиц совершать удивительные трюки. Любопытно, что в Haskell с самого начала было много людей, которые также знают шведский язык. Может быть, эта метафора - больше, чем просто метафора ...