在ghci中工作但不在文件中

Sat*_*vik 6 haskell

当我在加载文件之后尝试ghci中的某些内容时putStrLn $ showManyP "%d" 10 它会工作,但是为什么当我在文件中写入它时这不起作用 main = putStrLn $ showManyP "%d" 10

它给出了这个错误

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.
Run Code Online (Sandbox Code Playgroud)

实际文件从这里开始:

{-# 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 str@(x:xs) f | isPrefixOf f str = [[],drop (length f) str]
                   | otherwise = let (y:ys) = split xs f
                                 in [x:y] ++ ys
Run Code Online (Sandbox Code Playgroud)

pat*_*pat 9

在ghc中,当您输入数字常量时10,它可以是任何类型的实例Num.如果没有其他类型约束,则它是未确定的实例,并且您必须提供特定类型; 即(10 :: Int).Ghci是交互式的,必须向数字添加类型是一件痛苦的事情,所以它可以通过假设在没有其他类型约束的情况下,看起来像整数的东西是类型来帮助你Integer.这在GHC用户指南2.4.5中有解释.输入GHCi中的默认值

根据"2010 Haskell报告",在4.3.4模糊类型和重载数值运算的默认值中,有一个default关键字允许您在已编译的模块中利用此行为.

  • 这不完全正确.在编译的Haskell模块中键入默认_is_,相当于`default(Integer,Double)`的声明.但是在这种情况下它不适用,因为`Format`不是标准类.(见第一个链接).然而,在GHCi中,解除了这一限制. (3认同)