在ghci中工作,但不在文件中 [英] Works in ghci but not in the file
问题描述
当我在加载像 putStrLn $ showManyP%d10
这样的文件之后尝试使用ghci时,它可以工作,但为什么当我将它写入文件
main = putStrLn $ showManyP%d10
错误
printf.hs:37:19:
约束中含糊不清的类型变量`a0':$ b $在printf.hs:37:19-27处使用`showManyP'引起的b(格式a0):printf.hs:10:处产生的
(数字a0):37:34-35
可能的修复:添加一个修复这些类型变量的类型签名
在`($)'的第二个参数中,即`showManyP%d10
在表达式中:putStrLn $ showManyP%d10
在`main'等式中:main = putStrLn $ showManyP%d10
失败,加载模块:无。
实际档案从这里开始:
<$ p $ b $ {$#c $ {>#$ L $ $ $ $ { - #LANGUAGE FlexibleInstances# - }
{ - #LANGUAGE TypeSynonymInstances# - }
{ - #LANGUAGE UndecidableInstances# # - }
import Data.List(intercalate,isPrefixOf)
class Showable a where
showManyP :: String - > a
实例可显示的字符串其中
showManyP str = str
实例(可显示s,格式a)=> Showable(a-> s)其中
showManyP str a = showManyP(格式str a)
格式a其中
format :: String - > a - >字符串
实例格式字符串其中
格式str a =替换%sstr a
实例格式Char其中
格式str a =替换 %cstr [a]
实例Num a =>格式a其中
格式str a =替换%dstr(显示a)
replace :: String - >字符串 - >字符串 - > String
替换f str value =插入值$ split str f
split :: String - >字符串 - > [String]
split [] f = [[]]
split str [] = [str]
split str @(x:xs)f | isPrefixOf f str = [[],drop(length f)str]
|否则= let(y:ys)= split [x:y] ++ ys
10
这样的数字常量时,它可以是任何类型,它是货号
。如果没有附加的类型约束,它是一个未定的实例,你必须提供一个特定的类型;即(10 :: Int)
。 Ghci是交互式的,并且将数字类型添加到数字中将是一种痛苦,所以它通过假设在没有其他类型约束的情况下假设那些看起来像整数的事物类型为整数
。这在GHC用户指南 2.4.5 。在GHCi中输入违约 根据2010年哈斯克尔报告, 4.3.4模糊类型和重载数字操作的默认值,有一个默认值
关键字,它允许您在编译模块中利用这种行为。
when I try something in ghci after loading the file like putStrLn $ showManyP "%d" 10
it works but why this don't work when I write it in the file
main = putStrLn $ showManyP "%d" 10
It gives this error
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.
The actual file begins here:
{-# 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
In ghc, When you enter a numeric constant like 10
, it can be any type that is an instance of Num
. If there are no additional type constraints, it is an undecided instance, and you must provide a specific type; i.e. (10 :: Int)
. Ghci is interactive, and it would be a pain to have to add types to numbers, so it helps you out by assuming that, in the absence of additional type constraints, that things that look like integers are of type Integer
. This is explained in the GHC User Guide 2.4.5. Type defaulting in GHCi
According to the "2010 Haskell Report", in 4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations, there is a default
keyword that allows you to take advantage of this behavior in compiled modules.
这篇关于在ghci中工作,但不在文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!