Это toy-example.hs:
{-# LANGUAGE ImpredicativeTypes #-}
import Control.Arrow
data From = From (forall a. Arrow a => a Int Char -> a [Int] String)
data Fine = Fine (forall a. Arrow a => a Int Char -> a () String)
data Broken = Broken (Maybe (forall a. Arrow a => a Int Char -> a () String))
fine :: From -> Fine
fine (From f) = Fine g
where g :: forall a. Arrow a => a Int Char -> a () String
g x = f x <<< arr (const [1..5])
broken :: From -> Broken
broken (From f) = Broken (Just g) -- line 17
where g :: forall a. Arrow a => a Int Char -> a () String
g x = f x <<< arr (const [1..5])
И вот что думает об этом ghci:
GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> :l toy-example.hs
[1 of 1] Compiling Main ( toy-example.hs, interpreted )
toy-example.hs:17:32:
Couldn't match expected type `forall (a :: * -> * -> *).
Arrow a =>
a Int Char -> a () String'
with actual type `a0 Int Char -> a0 () String'
In the first argument of `Just', namely `g'
In the first argument of `Broken', namely `(Just g)'
In the expression: Broken (Just g)
Failed, modules loaded: none.
Почему fine
проверяет тип, а broken
нет?
Как заставить broken
проверять тип?
(В моем реальном коде я могу добавить параметр типа a
к Broken
, если это необходимо, вместо универсального количественного определения внутри конструктора, но я хотел бы избежать этого, если это возможно.)
Изменить: если я изменю определение Broken
на
data Broken = Broken (forall a. Arrow a => Maybe (a Int Char -> a () String))
затем broken
проверяет тип. Ура!
Но если я добавлю следующую функцию
munge :: Broken -> String
munge (Broken Nothing) = "something" -- line 23
munge (Broken (Just f)) = f chr ()
то я получаю сообщение об ошибке
toy-example.hs:23:15:
Ambiguous type variable `a0' in the constraint:
(Arrow a0) arising from a pattern
Probable fix: add a type signature that fixes these type variable(s)
In the pattern: Nothing
In the pattern: Broken Nothing
In an equation for `munge': munge (Broken Nothing) = "something"
Как мне заставить munge
также проверять тип?
2-е редактирование: в моей реальной программе я заменил конструктор Broken (Maybe ...)
конструкторами BrokenNothing
и BrokenJust ...
(уже были другие конструкторы), но мне любопытно, как в этой ситуации должно работать сопоставление с образцом.
data Broken = Broken (forall a. Arrow a => Maybe (a Int Char -> a () String))
. Я подозреваю, что в разделе 7.8 руководства GHC рассказывается, почему ваша версия не работает, точное обессахаривание фораллов - это не то, в чем я разбираюсь. - person stephen tetley   schedule 27.05.2011Nothing
. - person dave4420   schedule 27.05.2011