Подтвердить что ты не робот

Почему опечатка в объявлении функции Haskell приводит к тому, что GHCi бросает ошибки вокруг ранее компилируемого кода?

Вот какой-то странный вопрос. Изучая Haskell через LearnYouaHaskell, отличная книга, и я собираюсь реализовать различные примеры.

Это компилируется в GHCi

cylinder :: (RealFloat a) => a -> a -> a
cylinder r h =
    let sideArea = 2 * pi * r * h
    topArea = pi * r ^2
    in  sideArea + 2 * topArea

Это компилируется в GHCi

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
zipWith' _ [] _ = []  
zipWith' _ _ [] = []  
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys 

Если я намеренно создаю опечатку и объявляю вторую функцию так

zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]  
zipWith' _ [] _ = []  
zipWith' _ _ [] = []  
zipWith' f (x:xs) (y:ys) = f xs y : zipWith' f xs ys 

Затем первая и вторая функции бросают ошибки во время компиляции - по крайней мере, то, что я думаю, происходит.

Извините заранее за дамп кода.

Он выдает это ранее невидимое сообщение об ошибке о функции цилиндра, которую я не изменил

Prelude> :l functions2.hs
[1 of 1] Compiling Main             ( functions2.hs, interpreted )

functions2.hs:4:26:
    Could not deduce (Integral b0) arising from a use of ‘^’
    from the context (RealFloat a)
      bound by the type signature for
                 cylinder :: RealFloat a => a -> a -> a
      at functions2.hs:1:13-40
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Integral Int -- Defined in ‘GHC.Real’
      instance Integral Integer -- Defined in ‘GHC.Real’
      instance Integral GHC.Types.Word -- Defined in ‘GHC.Real’
    In the second argument of ‘(*)’, namely ‘r ^ 2’
    In the expression: pi * r ^ 2
    In an equation for ‘topArea’: topArea = pi * r ^ 2

functions2.hs:4:27:
    Could not deduce (Num b0) arising from the literal ‘2’
    from the context (RealFloat a)
      bound by the type signature for
                 cylinder :: RealFloat a => a -> a -> a
      at functions2.hs:1:13-40
    The type variable ‘b0’ is ambiguous
    Note: there are several potential instances:
      instance Num Double -- Defined in ‘GHC.Float’
      instance Num Float -- Defined in ‘GHC.Float’
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      ...plus three others
    In the second argument of ‘(^)’, namely ‘2’
    In the second argument of ‘(*)’, namely ‘r ^ 2’
    In the expression: pi * r ^ 2

Как и это гораздо более разумное сообщение об ошибке в опечатке во второй функции

functions2.hs:12:30:
    Couldn't match expected type ‘a’ with actual type ‘[a]’
      ‘a’ is a rigid type variable bound by
          the type signature for
            zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
          at functions2.hs:9:13
    Relevant bindings include
      xs :: [a] (bound at functions2.hs:12:15)
      x :: a (bound at functions2.hs:12:13)
      f :: a -> b -> c (bound at functions2.hs:12:10)
      zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
        (bound at functions2.hs:10:1)
    In the first argument of ‘f’, namely ‘xs’
    In the first argument of ‘(:)’, namely ‘f xs y’
Failed, modules loaded: none. 

Почему? Это обычная ошибка? Разрывал ли я что-то в первом, разрушая второе? Просьба сообщить.

4b9b3361

Ответ 1

Это был билет ошибки GHС# 9033, который был опубликован в апреле 2014 года и быстро исправлен.

В принципе, всякий раз, когда файл содержит почти любую ошибку типа, GHC пропускает шаг дефолта класса типа, что может привести к тому, что другие части файла будут давать ложные неоднозначные ошибки типа.

Как отмечает @leftaroundabout, оператор ^ является частым триггером этого, так как его второй тип аргумента не связан с другими типами и поэтому очень часто требуется дефолт.

Версия GHC, указанная в билете 7.8.2, и 7.8.3 была выпущена в июле 2104, поэтому я предполагаю, что версии 7.8.3 и позже имеют исправление.