使用Haskell的“Maybe”,键入声明[初学者的问题] [英] Using Haskell's "Maybe", type declarations [beginner's question]
问题描述
我开始尝试使用Haskell并遇到问题。 qqq是一个函数,如果用Nothing调用时应该打印一个字符串,如果用Just something调用,则打印其他东西。
第一次尝试似乎正在工作:
qqq Nothing = print没有要打印的东西。
qqq(Just x)= print有东西需要打印。 >>打印x
main :: IO()
main = qqq(只需43)
但是:当我尝试制作 main = qqq(Nothing)时,
它失败了(在使用'qqq'时产生的约束(显示a0)'中的不明确类型变量'a0')
-
qqq :: Maybe x => x - > IO()
- >类型构造函数'Maybe'用作类
- >但是不是?
IO()。现在签名本身看起来很成功。但是
main = qqq(只是43)开始以(Show a0)
c> main = qqq(Nothing) case。问题:
- 为什么用
Nothing调用qqq
与调用只要43
? - 什么是
(显示a0)
?仅在错误消息中提及。任何尝试使用它都会导致类似不在范围内显示。 - 什么是正确的类型签名?如何制作Haskell打印类型签名?期望如下所示:
f 0 = 2
fx =(f(x-1))+ 3
main = print get_type_as_string(f)
- 打印Number - > Number
解决方案
qqq 的类型是:
qqq ::显示a =>也许是 - > IO()
这意味着
qqq
需要一个类型的参数可能是一个
并返回一个没有值的IO动作,约束 实现了Show
typeclass。要找出显示
是什么,你可以在ghci中使用:i显示
。
Show 是一个类型类,它要求类型的值可以转换为字符串。
qqq
有约束,因为print $ c> $ c>键入
显示a => a - > IO()
)。也许
不是类型类型,而是数据类型。您可以阅读更多关于此处的类别类。
<您可以让GHC通过在.hs文件中输入函数,然后用ghci(ghci Myfile.hs
)加载文件来推断类型签名,然后键入:t qqq
来显示类型。您还可以在交互式会话中使用let qqq n = case n of {Nothing - >打印abc;只要x - >打印def>> print x}
(它看起来有点不同,因为函数定义必须在ghci的一行上,但含义相同)。
<当主调用qqq
时,qqq(只要43)
,清楚<$ c $的具体类型c>也许一个是一个数字类型(ghci默认为Integer),所以qqq
的具体类型为也许整数 - > IO()
。然而,主调用qqq
并且qqq Nothing
,a
可以做任何事情(这是不明确的),ghci报告错误。I've started experimenting with Haskell and have a problem. qqq is a function that should print one string if called with "Nothing" and print other things if called with "Just something".
The first attempt seems like working:
qqq Nothing = print "There isn't anything to be printed." qqq (Just x) = print "There is something to be printed." >> print x main :: IO () main = qqq (Just 43)
But:
- when I try to make
main = qqq (Nothing)
it fails ("Ambiguous type variable `a0' in the constraint: (Show a0) arising from a use of 'qqq'")- When I want to add type signature if fails:
qqq :: Maybe x => x -> IO ()
->Type constructor 'Maybe' used as a class
-> But isn't it?
qqq :: (Maybe x) -> IO ()
. Now the signature itself looks like succeed. Butmain = qqq (Just 43)
starts failing with that mysterious(Show a0)
error like inmain = qqq (Nothing)
case.Questions:
- Why calling qqq with
Nothing
is so different than calling withJust 43
?- What is
(Show a0)
? It is mentioned only in error messages. Any attempts to use it lead to something like "Show not in the scope".- What is correct type signature for this? How to make Haskell print type signature it deduced? Expecting something like:
f 0 = 2 f x = (f (x-1)) + 3 main = print get_type_as_string(f) -- prints "Number -> Number"
解决方案The type of
qqq
is:qqq :: Show a => Maybe a -> IO ()
That means that
qqq
takes one parameter of typeMaybe a
and returns an IO action without a value, with the constraint thata
implements theShow
typeclass. To find out whatShow
is, you can use:i Show
in ghci.
Show
is a typeclass which requires that a value of the type can be converted to a string.qqq
has the constraint becauseShow a => a -> IO ()
).Maybe
is not a typeclass but a data type. You can read more about typeclasses here.You can let GHC deduce the type signature either by typing the function in a .hs file, then loading the file with ghci (
ghci Myfile.hs
), and then typing:t qqq
for displaying the type. You can also define the function in the interactive session withlet qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x }
(it looks a bit different because the function definition has to be on one line in ghci, but the meaning is the same).When main calls
qqq
withqqq (Just 43)
, it is clear the concrete type ofMaybe a
is a numeric type (ghci defaults to Integer), soqqq
has the concrete type ofMaybe Integer -> IO ()
. However, main callsqqq
withqqq Nothing
,a
could be anything (it is ambiguous) and ghci reports an error.这篇关于使用Haskell的“Maybe”,键入声明[初学者的问题]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文