проблемы с Типами Числа Haskell

У меня есть следующий код haskell:

fac n = product [1..n]

taylor3s w0 f f' f'' t h = w1 : taylor3s w1 f f' f'' (t+h) h
  where hp i = h^i / fac i
        w1 = w0 + (hp 1) * f t w0 + (hp 2) * f' t w0 + (hp 3) * f'' t w0

taylor_results = take 4 $ taylor3s 1 f f' f'' 1 0.25
  where f   t x = t^4 - 4*x/t
        f'  t x = 4*t^3 - 4*(f t x)/t + 4*x/t^2
        f'' t x = 12*t^2 - 4*(f' t x)/t + 8*(f t x)/t^2 - 8*x/t^3

taylor_results, как предполагается, является вариантом использования taylor3s. Однако существует что-то не так с выводом типа числа. Когда я пытаюсь скомпилировать, это - ошибка, которую я получаю:

practice.hs:93:26:
    Ambiguous type variable `a' in the constraints:
      `Integral a'
        arising from a use of `taylor3s' at practice.hs:93:26-51
      `Fractional a' arising from a use of `f' at practice.hs:93:37
    Possible cause: the monomorphism restriction applied to the following:
      taylor_results :: [a] (bound at practice.hs:93:0)
    Probable fix: give these definition(s) an explicit type signature
                  or use -XNoMonomorphismRestriction

Кто-то может помочь мне с пониманием, какова проблема?

5
задан mindeavor 15 May 2010 в 07:31
поделиться

2 ответа

Поскольку вы смешиваете операции, доступные только для интегралов, и операции, доступные только для дробей (в частности, вы используете ^, из которых второй операнд должен быть интегралом - используйте **, если вы хотите, чтобы оба операнда имели одинаковый тип Floating), haskell выводит, что все аргументы и результат taylor3s имеют тип Fractional a, Integral a => a. Это не ошибка типа, так как теоретически такой тип может существовать, но, скорее всего, это не то, что вы хотите, потому что на практике такого типа не существует.

Причина, по которой вы все равно получаете ошибку типа, заключается в том, что предполагаемый тип taylor_results, следовательно, также Fractional a, Integral a => a, который является полиморфным и, таким образом, нарушает ограничение мономорфизма.

Если бы вы явно объявили taylor_results как taylor_results :: Fractional a, Integral a => a или отключить ограничение на мономорфизм, все это скомпилируется, но будет невозможно использовать (без определения типа, который фактически инстанцирует Integral и Fractional, что было бы бессмыслицей).

Обратите внимание, что если исправить это (например, заменив ^ на **), то тип taylor_results все равно будет полиморфным (он будет выводиться как taylor_results :: (Floating a, Enum a) => [a], что на самом деле разумно), поэтому вы все равно столкнетесь с ограничением на мономорфизм. Поэтому вам нужно либо отключить это ограничение, либо явно объявить тип taylor_results полиморфным, либо явно объявить тип taylor_results определенным типом, который инстанцирует Floating и Enum (например, Double). Обратите внимание, что если вы не сделаете последнее, taylor_results будет пересчитываться каждый раз, когда вы будете его использовать (именно поэтому существует ограничение на мономорфизм).

Обратите внимание, что если вы исправите это (например, заменив ^ на **), то наиболее общий тип taylor_results будет (Floating a, Enum a) => [a], однако тип, который вы получите (если не отключите ограничение мономорфизма), будет [Double]. Если вам не нужны двойники, то вам придется либо явно объявить taylor_results другим типом (который инстанцирует Floating и Enum), либо полиморфным. Обратите внимание, что если вы объявите его полиморфным, taylor_results будет пересчитываться каждый раз, когда вы его используете (именно поэтому существует ограничение на мономорфизм).

8
ответ дан 14 December 2019 в 04:32
поделиться

Похоже, что Haskell считает возврат taylor3s типом Integral, но тот факт, что подфункции f и т.д. считаются работающими с Fractional типами, нарушает это предположение.

Возможно, явное указание в Haskell возвращаемого типа taylor3s может помочь.

0
ответ дан 14 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

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