2011-10-17 23 views
6

gdy próbuję coś ghci po wczytaniu pliku jak putStrLn $ showManyP "%d" 10 to działa, ale dlaczego to nie działają, gdy piszę je w pliku main = putStrLn $ showManyP "%d" 10Pracuje w ghci ale nie w pliku

Daje ten błąd

printf.hs:37:19: 
Ambiguous type variable `a0' in the constraints: 
    (Format a0) arising from a use of `showManyP' at printf.hs:37:19-27 
    (Num a0) arising from the literal `10' at printf.hs:37:34-35 
Probable fix: add a type signature that fixes these type variable(s) 
In the second argument of `($)', namely `showManyP "%d" 10' 
In the expression: putStrLn $ showManyP "%d" 10 
In an equation for `main': main = putStrLn $ showManyP "%d" 10 
Failed, modules loaded: none. 

rzeczywisty plik zaczyna się tutaj:

{-# LANGUAGE OverlappingInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE TypeSynonymInstances #-} 
import Data.List (intercalate,isPrefixOf) 
class Showable a where 
    showManyP :: String -> a 

instance Showable String where 
    showManyP str = str 

instance (Showable s,Format a) => Showable (a->s) where 
    showManyP str a = showManyP (format str a) 

class Format a where 
    format :: String -> a -> String 

instance Format String where 
    format str a = replace "%s" str a 

instance Format Char where 
    format str a = replace "%c" str [a] 

instance Num a=>Format a where 
    format str a = replace "%d" str (show a) 

replace :: String -> String -> String -> String 
replace f str value = intercalate value $ split str f 

split :: String -> String -> [String] 
split [] f = [[]] 
split str [] = [str] 
split [email protected](x:xs) f | isPrefixOf f str = [[],drop (length f) str] 
        | otherwise = let (y:ys) = split xs f 
           in [x:y] ++ ys 

Odpowiedz

9

W GHC, Po wpisaniu numerycznej stałej jak 10, może to być dowolny typ, który jest instancją Num. Jeśli nie ma żadnych dodatkowych ograniczeń typu, jest to niezdecydowana instancja i trzeba podać określony typ; tj. (10 :: Int). Ghci jest interaktywny i byłoby to trudne, gdyby trzeba było dodawać typy do liczb, więc pomaga ci to, zakładając, że przy braku dodatkowych ograniczeń typu rzeczy wyglądające na liczby całkowite są typu Integer. Jest to wyjaśnione w podręczniku użytkownika GHC 2.4.5. Type defaulting in GHCi

Według „Raportu 2010 Haskell”, w 4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations, istnieje default słowo kluczowe, które pozwala, aby skorzystać z tego zachowania w skompilowanych modułów.

+3

To nie jest całkowicie poprawne. Wpisz domyślne _is_ włączone w skompilowanych modułach Haskella, równoważne deklaracji 'default (Integer, Double)'. Jednak nie jest on stosowany w tym przypadku, ponieważ 'Format' nie jest klasą standardową. (Zobacz swój pierwszy link). W GHCi jednak to ograniczenie zostaje zniesione. – hammar

+0

Czy możesz powiedzieć, jak dodać domyślną deklarację dla Format w powyższym przypadku ..? – Satvik