Was ist die Monomorphismusbeschränkung?

Ich bin verwirrt darüber, wie der Haskell-Compiler manchmal Typen ableitet, die weniger polymorph sind als erwartet, zum Beispiel bei der Verwendung von punktfreien Definitionen.

Es scheint, dass das Problem die "Monomorphismus-Einschränkung" ist, die in älteren Versionen des Compilers standardmäßig aktiviert ist.

Betrachten Sie das folgende Haskell-Programm:

{-# LANGUAGE MonomorphismRestriction #-}

import Data.List(sortBy)

plus = (+)
plus' x = (+ x)

sort = sortBy compare

main = do
  print $ plus' 1.0 2.0
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]

Wenn ich das mit @ kompilieghc Ich erhalte keine Fehler und die Ausgabe der ausführbaren Datei lautet:

3.0
3.0
[1,2,3]

Wenn ich das @ ändemain body to:

main = do
  print $ plus' 1.0 2.0
  print $ plus (1 :: Int) 2
  print $ sort [3, 1, 2]

Ich erhalte keine Fehler bei der Kompilierung und die Ausgabe lautet:

3.0
3
[1,2,3]

wie erwartet. Wenn ich jedoch versuche, es zu ändern:

main = do
  print $ plus' 1.0 2.0
  print $ plus (1 :: Int) 2
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]

Ich erhalte einen Tippfehler:

test.hs:13:16:
    No instance for (Fractional Int) arising from the literal ‘1.0’
    In the first argument of ‘plus’, namely ‘1.0’
    In the second argument of ‘($)’, namely ‘plus 1.0 2.0’
    In a stmt of a 'do' block: print $ plus 1.0 2.0

Das gleiche passiert beim Versuch, @ anzurufsort zweimal mit verschiedenen Typen:

main = do
  print $ plus' 1.0 2.0
  print $ plus 1.0 2.0
  print $ sort [3, 1, 2]
  print $ sort "cba"

erzeugt den folgenden Fehler:

test.hs:14:17:
    No instance for (Num Char) arising from the literal ‘3’
    In the expression: 3
    In the first argument of ‘sort’, namely ‘[3, 1, 2]’
    In the second argument of ‘($)’, namely ‘sort [3, 1, 2]’
Warum tutghc plötzlich denke, dassplus ist nicht polymorph und benötigt einInt Streit? Der einzige Verweis aufInt ist ineine Bewerbun vonplus, wie kann das wichtig sein, wenn die Definition eindeutig polymorph ist?Warum tutghc plötzlich denke, dasssort erfordert eineNum Char instance?

Mehr, wenn ich versuche, die Funktionsdefinitionen in ihrem eigenen Modul zu platzieren, wie in:

{-# LANGUAGE MonomorphismRestriction #-}

module TestMono where

import Data.List(sortBy)

plus = (+)
plus' x = (+ x)

sort = sortBy compare

Ich erhalte den folgenden Fehler beim Kompilieren:

TestMono.hs:10:15:
    No instance for (Ord a0) arising from a use of ‘compare’
    The type variable ‘a0’ is ambiguous
    Relevant bindings include
      sort :: [a0] -> [a0] (bound at TestMono.hs:10:1)
    Note: there are several potential instances:
      instance Integral a => Ord (GHC.Real.Ratio a)
        -- Defined in ‘GHC.Real’
      instance Ord () -- Defined in ‘GHC.Classes’
      instance (Ord a, Ord b) => Ord (a, b) -- Defined in ‘GHC.Classes’
      ...plus 23 others
    In the first argument of ‘sortBy’, namely ‘compare’
    In the expression: sortBy compare
    In an equation for ‘sort’: sort = sortBy compare
Warum ist nichtghcn der Lage, den polymorphen Typ zu verwendOrd a => [a] -> [a] zumsort?nd warum machtghc treatplus undplus' anders?plus sollte den polymorphen Typ @ habNum a => a -> a -> a und ich sehe nicht wirklich, wie sich das von der Art von @ unterscheidsort und doch nursort raises an error.<p>Last thing: if I comment the definition of <code>sort</code> the file compiles. However if I try to load it into <code>ghci</code> and check the types I get:</p><pre class="lang-none prettyprint-override"><code>*TestMono> :t plus plus :: Integer -> Integer -> Integer *TestMono> :t plus' plus' :: Num a => a -> a -> a </code></pre><p>Why isn't the type for <code>plus</code> polymorphic?</p>

This is the canonical question about monomorphism restriction in Haskell as discussed in <a href="https://meta.stackoverflow.com/questions/294053/can-we-provide-a-canonical-questionanswer-for-haskells-monomorphism-restrictio" rel="nofollow">the meta question</a>.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage