理解旧考试中的Haskell类型 [英] Understanding a Haskell type from an old exam
问题描述
我正在学习Haskell考试,并且在这个问题上有点卡住:
我的第一个想法是写这样的东西
paste :: Region - >图片a - >图片a - > Image a a b $ b paste(Image bol)img1 img2 = if bol
then - do the pasting
else - well do nothing
但我不知道如何做粘贴。有人能指点我吗?
虽然这在实际参加考试时用处不大, 教导一个人去拖网捕鱼回答:首先没有定义任何结果,让编译器(必须是GHC≥7.8)注释它。请注意,存根错误:如果 Image
只是类型
-def,则不需要值构造函数图像
可以匹配它。
newtype图片a =图片位置 - > a)
- 它应该是`newtype`而不是`type`,否则
- 不会是显式的`Image`值构造函数
类型Position = (Float,Float)
类型Region =图片Bool
粘贴::区域 - >图片a - >图片a - >图片a
贴图(图片大图)img1 img2 = _
/ p>
/tmp/wtmpf-file6644.hs:8:31:
找到类型为'_'的洞:图片a
其中:'a'是一个由$ b $绑定的刚性类型变量
的类型签名paste :: Region - >图片a - >图片a - >图片a
...
好吧,这并不奇怪:我们已经知道结果应该是一个图像。现在,对于 Image
,即 Image
只有一个构造函数,所以我们确实知道我们需要构造这样一个图片。仍然不知道有关内部实现的任何内容:
粘贴(图片大小)img1 img2 =图片_
给出
/tmp/wtmpf-file6644.hs:8:37:
找到类型为'_'的孔:位置 - > a
其中:'a'是由
绑定的刚性类型变量
的类型签名paste :: Region - >图片a - >图片a - >图片在/tmp/wtmpf-file6644.hs:7:10
的图片a
Aha,所以隐藏在 Image
中的额外函数参数!让我们来模式匹配:
粘贴(图片大小)img1 img2 =图像$ \pos - > _
/tmp/wtmpf-file6644.hs:8:47:
找到类型为'a'的孔'_'b $ b ...
好吧,
a
是完全不透明的,所以现在我们知道肯定有 >没有进一步的信息,我们无法做到这一点。幸运的是,我们确实有更多的信息,以参数的形式出现。由于GHC会通知您:
...
相关绑定包括
pos :: Position(bound在/tmp/wtmpf-file6644.hs:8:40)
img2 ::图片a(绑定在/tmp/wtmpf-file6644.hs:8:24)
img1 ::图片a(bound at /tmp/wtmpf-file6644.hs:8:19)
bol :: Position - > Bool(绑定在/tmp/wtmpf-file6644.hs:8:14)
没有很多我们可以这样做......这很好,因为这明显地表明了应完成的事情:我们可以提供
- >如果是波币pos
作为bol
的参数。结果输入Bool
(不同于bol
本身),所以现在是<$ c
$ b $ $ p $粘贴(图片大小)img1 img2 =图片$ \pos {$ c> if if
switch。
那么_
else _
...
发现类型为'a'的洞'_'...
之前,我们需要更多的信息。让我们回顾一下这些参数: Image a
仍然可以进行模式匹配
粘贴(Image bol)(Image img1)(Image img2)
=图片$ \pos - >如果是波币
然后_
其他_
现在它说: p>
相关绑定包括
pos :: Position(绑定在/tmp/wtmpf-file6644.hs:9:14)
img2 ::位置 - > a(绑定在/tmp/wtmpf-file6644.hs:8:39)
img1 ::位置 - > a(绑定在/tmp/wtmpf-file6644.hs:8:26)
bol :: Position - > Bool(绑定在/tmp/wtmpf-file6644.hs:8:14)
Aha,所以<根据我们的需要,code> img1 和 img2
可以产生一个 a
我们只需要它们首先提供位置
。那么,我们仍然有 pos
,所以很明显该怎么办:
粘贴(Image bol)(Image img1)(Image img2)
=图片$ \pos - >如果bol pos
,那么img1 pos
else img2 pos
...或两个图像交换(自己想想)。但是,只有给定的信息(以及它们的 all !)才能写出任何其他定义,因此这种类型化的过程是实现函数的一种相当简单的方法。 p>
I am studying for a Haskell exam and I'm a bit stuck on this question:
My first thought was to write something like this
paste :: Region -> Image a -> Image a -> Image a
paste (Image bol) img1 img2 = if bol
then -- do the pasting
else -- well do nothing
But I don't know how to do the pasting. Can someone point me in the right direction?
While this is little use when you're actually sitting in an exam, here's the "teach a man to trawl-fish" answer: start out without defining any result at all, and let the compiler (must be GHC≥7.8) comment on it. Note that the stub is wrong: if Image
is just a type
-def, you don't need the value constructor Image
to pattern match on it.
newtype Image a = Image (Position -> a)
-- it should be `newtype` instead of `type`, else there
-- won't be an explicit `Image` value constructor
type Position = (Float, Float)
type Region = Image Bool
paste :: Region -> Image a -> Image a -> Image a
paste (Image bol) img1 img2 = _
GHC will come back with
/tmp/wtmpf-file6644.hs:8:31:
Found hole ‘_’ with type: Image a
Where: ‘a’ is a rigid type variable bound by
the type signature for
paste :: Region -> Image a -> Image a -> Image a
...
Ok, that's hardly surprising: we already know that the result should be an image. Now, there's only one contructor for Image
, namely Image
, so we know for sure we need that to construct such an image. Still don't know anything about the inner implementation:
paste (Image bol) img1 img2 = Image _
gives
/tmp/wtmpf-file6644.hs:8:37:
Found hole ‘_’ with type: Position -> a
Where: ‘a’ is a rigid type variable bound by
the type signature for
paste :: Region -> Image a -> Image a -> Image a
at /tmp/wtmpf-file6644.hs:7:10
Aha, so there's an extra function argument lurking hidden in the Image
! Let's pattern match on that, too:
paste (Image bol) img1 img2 = Image $ \pos -> _
/tmp/wtmpf-file6644.hs:8:47:
Found hole ‘_’ with type: a
...
Ok, a
is completely opaque, so now we know for sure there's nothing we can do without further information. Fortunately, we do have further information, in form of the arguments. As GHC will inform you:
...
Relevant bindings include
pos :: Position (bound at /tmp/wtmpf-file6644.hs:8:40)
img2 :: Image a (bound at /tmp/wtmpf-file6644.hs:8:24)
img1 :: Image a (bound at /tmp/wtmpf-file6644.hs:8:19)
bol :: Position -> Bool (bound at /tmp/wtmpf-file6644.hs:8:14)
There's not much we can do with that... which is good, because this makes it obvious what should be done: we can feed pos
as an argument to bol
. The result has then type Bool
(unlike bol
itself), so that is now a good candidate for an if
switch.
paste (Image bol) img1 img2 = Image $ \pos -> if bol pos
then _
else _
...
Found hole ‘_’ with type: a
...
seen that before, so again we need more information. Let's look back at those arguments: Image a
can still be pattern matched
paste (Image bol) (Image img1) (Image img2)
= Image $ \pos -> if bol pos
then _
else _
Now it says:
Relevant bindings include
pos :: Position (bound at /tmp/wtmpf-file6644.hs:9:14)
img2 :: Position -> a (bound at /tmp/wtmpf-file6644.hs:8:39)
img1 :: Position -> a (bound at /tmp/wtmpf-file6644.hs:8:26)
bol :: Position -> Bool (bound at /tmp/wtmpf-file6644.hs:8:14)
Aha, so img1
and img2
can yield an a
value as we need, we just need them to feed a Position
first. Well, we still have pos
, so it's obvious what to do:
paste (Image bol) (Image img1) (Image img2)
= Image $ \pos -> if bol pos
then img1 pos
else img2 pos
...or with the two images swapped (think about that yourself). But there aren't really any other definitions you can write using only the given information (and all of it!), so this typed-hole procedure is a pretty foolproof way of implementing a function.
这篇关于理解旧考试中的Haskell类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!