Folgende Programmtyp-Kontrollen:Warum muss ein Funktionstyp "umgebrochen" werden, damit der Typüberprüfer erfüllt wird?
{-# LANGUAGE RankNTypes #-}
import Numeric.AD (grad)
newtype Fun = Fun (forall a. Num a => [a] -> a)
test1 [u, v] = (v - (u * u * u))
test2 [u, v] = ((u * u) + (v * v) - 1)
main = print $ fmap (\(Fun f) -> grad f [1,1]) [Fun test1, Fun test2]
Aber dieses Programm fehlschlägt:
main = print $ fmap (\f -> grad f [1,1]) [test1, test2]
Mit dem Typ-Fehler:
Grad.hs:13:33: error:
• Couldn't match type ‘Integer’
with ‘Numeric.AD.Internal.Reverse.Reverse s Integer’
Expected type: [Numeric.AD.Internal.Reverse.Reverse s Integer]
-> Numeric.AD.Internal.Reverse.Reverse s Integer
Actual type: [Integer] -> Integer
• In the first argument of ‘grad’, namely ‘f’
In the expression: grad f [1, 1]
In the first argument of ‘fmap’, namely ‘(\ f -> grad f [1, 1])’
letztere Programm sieht Intuitiv richtig. Schließlich hat die folgende, scheinbar gleichwertige Programmarbeit:
main = print $ [grad test1 [1,1], grad test2 [1,1]]
Es sieht aus wie eine Beschränkung in Art System GHC. Ich würde gerne wissen, was den Fehler verursacht, warum diese Einschränkung existiert, und mögliche Problemumgehungen neben dem Umbruch der Funktion (per Fun
oben).
. (Anmerkung: dies durch die Monomorphie Beschränkung nicht verursacht wird; Kompilieren mit NoMonomorphismRestriction
hilft nicht)
Könnte dies die gefürchtete Monomorphie-Einschränkung sein? –
Es ist nicht die Monomorphie-Einschränkung. – frasertweedale
Dies ist in der Tat eine Einschränkung im Typsystem. Das fehlerhafte Programm würde erfordern, dass impredikative Typen korrekt typisiert werden ("[test1, test2] :: [forall a. ...]" ist impredicativ), was als [docs] (https: //downloads.haskell. org/~ ghc/neuste/docs/html/users_guide/glasgow_exts.html # impredikativer Polymorphismus), hat GHC nur "extrem flockige Unterstützung" für. Die beste Problemumgehung ist ein 'newtype'-Wrapper. Alternativ können Sie "ImpredicativeTypes" aktivieren und jedem Unterbefehl des Programms Typanmerkungen hinzufügen, bis die Überprüfung erfolgt. – user2407038