2016-04-01 12 views
0

Ich schreibe gerade einen einfachen Code in Haskell,Mehrdeutige Instanz in Haskell

coo x y = ((lim-1)*y*(y-1)`div`2) + (y*(y-1)*(sum (map (\j->(x`div`j)-j) [2..lim]))) 
    where 
    lim = floor (sqrt x) 

aber wenn ich 'coo 10 10' in GHCI, es gibt mir die folgende Fehlermeldung:

<interactive>:3:1: 
No instance for (Floating a0) arising from a use of ‘it’ 
The type variable ‘a0’ is ambiguous 
Note: there are several potential instances: 
    instance Floating Double -- Defined in ‘GHC.Float’ 
    instance Floating Float -- Defined in ‘GHC.Float’ 
In the first argument of ‘print’, namely ‘it’ 
In a stmt of an interactive GHCi command: print it 

Was passiert? Ich bin mir sicher, dass ich alle Typen richtig zuordnen kann.

+0

Sie werden eine explizite Art Signatur für (oder innerhalb) 'coo 10 10' selbst brauchen. Um zu sehen warum, tippe ": t coo" in GHCi. Die Typen sind korrekt, aber "coo 10 10" ist immer noch polymorph. Sie müssen angeben, ob Sie 'coo 10 10 :: Float' oder' coo 10 10 :: Double' möchten. –

+0

@Rhymoid Nope ... obwohl der Fehler darauf hinweisen würde, ist es hier nicht das Problem - versuchen Sie es: Sie werden nur einen anderen Fehler bekommen (sagen Sie 'Float' oder' Double' ist nicht 'Integral') – Carsten

+0

' sqrt :: Floating a => a -> a'; Sie können 'sqrt (fromIntegral x)' verwenden, aber achten Sie auf Präzisionsverlust. – Ryan

Antwort

4

Wenn Sie genau hinsehen (oder fragen GHCi) Sie werden sehen, dass Ihre Funktion den Typ hat

coo :: (Floating a, Integral a, RealFrac a) => a -> a -> a 

GHC sagen a irgendeine Art zu verwenden, die sowohl eine Floating und ein Integral und dies wird schwierig bekommen (gibt es keine solche Typen im Prelude)


ich bin nicht 100% sicher, was Sie versuchen, dies zu tun, sondern eine Möglichkeit, zu beheben ist lim in ändern:

lim = floor (sqrt $ fromIntegral x) 

wird diese Ausbeute

λ> coo 10 10 
360 
+0

Können Sie vorschlagen, wie Sie dieses Problem beheben können? – CYC

+1

erledigt - aber ich weiß nicht, was Ihre Funktion tun soll – Carsten

+0

Der richtige Weg wäre die Funktion [Integer-Quadratwurzel] (https://en.m.wikipedia.org/wiki/Integer_square_root) zu implementieren. –