2011-10-17 20 views
6

khi tôi thử một cái gì đó trong ghci sau khi tải các tập tin như putStrLn $ showManyP "%d" 10 nó hoạt động nhưng tại sao điều này không hoạt động khi tôi viết nó trong file main = putStrLn $ showManyP "%d" 10trình trong ghci nhưng không phải trong file

Nó cho lỗi này

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. 

Các tập tin thực sự bắt đầu ở đây:

{-# 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 

Trả lời

9

Trong GHC, Khi bạn nhập một hằng số như 10, nó có thể là bất kỳ loại nào là một ví dụ của Num. Nếu không có ràng buộc kiểu bổ sung nào, nó là một cá thể chưa quyết định, và bạn phải cung cấp một kiểu cụ thể; tức là (10 :: Int). Ghci là tương tác, và nó sẽ là một nỗi đau khi phải thêm các loại vào các số, do đó, nó giúp bạn bằng cách giả định rằng, trong trường hợp không có các ràng buộc kiểu bổ sung, những thứ giống như số nguyên là loại Integer. Điều này được giải thích trong Hướng dẫn sử dụng GHC 2.4.5. Type defaulting in GHCi

Theo "Báo cáo Haskell 2010", trong 4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations, có từ khóa default cho phép bạn tận dụng lợi thế của hành vi này trong các mô-đun được biên dịch.

+3

Điều này không hoàn toàn chính xác. Loại mặc định _is_ được kích hoạt trong các mô-đun Haskell đã biên dịch, tương đương với khai báo 'mặc định (Số nguyên, Đôi)'. Tuy nhiên nó không được áp dụng trong trường hợp này, bởi vì 'Định dạng' không phải là một lớp tiêu chuẩn. (Xem liên kết đầu tiên của bạn). Tuy nhiên, trong GHCi, hạn chế này được dỡ bỏ. – hammar

+0

Bạn có thể cho biết cách thêm khai báo mặc định cho Định dạng trong trường hợp trên ..? – Satvik

Các vấn đề liên quan