Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从旧考试中理解Haskell类型_Haskell - Fatal编程技术网

从旧考试中理解Haskell类型

从旧考试中理解Haskell类型,haskell,Haskell,我正在准备Haskell考试,我有点被这个问题困住了: 我的第一个想法是写这样的东西 paste :: Region -> Image a -> Image a -> Image a paste (Image bol) img1 img2 = if bol then -- do the pasting else -- well do nothing 但是我

我正在准备Haskell考试,我有点被这个问题困住了:

我的第一个想法是写这样的东西

paste :: Region -> Image a -> Image a -> Image a
paste (Image bol) img1 img2 = if bol
                              then -- do the pasting
                              else -- well do nothing

但是我不知道怎么粘贴。有人能给我指出正确的方向吗?

好的。您的屏幕坐标由[0,1]×[0,1]矩形表示。区域是该矩形上的布尔函数,当且仅当坐标位于该区域时,该函数才返回true。然后有两个图像,img1和img2,它们是从坐标到像素的映射,或者理论上是到其他对象的映射

您希望返回一个新图像,对于reg内的坐标等于img1,对于reg外的坐标等于img2。图像是从坐标到像素的映射,因此您实际上返回了一个函数

类型是Region->Image a->Image a->Image a,但是请记住,Image a是Position->a,Region是Image Bool,所以这实际上是Position->Bool->Position->a->Position->a->Position->Position a。我们需要->a之前的最终位置参数,并将其作为三个函数参数的参数

所以,

paste :: Region -> Image a -> Image a -> Image a
-- Is really: (Position->Bool) -> (Position->a) -> (Position->a) -> Position -> a
paste reg overlay bg coords | reg coords == True = overlay coords
                            | otherwise          = bg coords
带有测试用例的较长版本:

module Image where

type Image a = Position -> a
type Position = (Float, Float) -- [0,1]×[0,1]

data Color = RGB Int Int Int -- Pixels have values in [0,255]×[0,255]×[0,255].
  deriving Show
-- Not efficient for real-world use, but will do for now.

type Region = Image Bool
type ColorImage = Image Color

paste :: Region -> Image a -> Image a -> Image a
-- Is really: (Position->Bool) -> (Position->a) -> (Position->a) -> Position -> a
paste reg overlay bg coords | reg coords == True = overlay coords
                            | otherwise          = bg coords

allRed :: ColorImage
allRed _ = RGB 255 0 0

allWhite :: ColorImage
allWhite _ = RGB 255 255 255

unitCircle :: Region
unitCircle (x,y) = sqrt (x'*x' + y'*y') <= 0.5
  where x' = x - 0.5
        y' = y - 0.5

redCircleOnWhite :: ColorImage
redCircleOnWhite = paste unitCircle allRed allWhite

您可以在REPL中测试redCircleOnWhite。

好的。您的屏幕坐标由[0,1]×[0,1]矩形表示。区域是该矩形上的布尔函数,当且仅当坐标位于该区域时,该函数才返回true。然后有两个图像,img1和img2,它们是从坐标到像素的映射,或者理论上是到其他对象的映射

您希望返回一个新图像,对于reg内的坐标等于img1,对于reg外的坐标等于img2。图像是从坐标到像素的映射,因此您实际上返回了一个函数

类型是Region->Image a->Image a->Image a,但是请记住,Image a是Position->a,Region是Image Bool,所以这实际上是Position->Bool->Position->a->Position->a->Position->Position a。我们需要->a之前的最终位置参数,并将其作为三个函数参数的参数

所以,

paste :: Region -> Image a -> Image a -> Image a
-- Is really: (Position->Bool) -> (Position->a) -> (Position->a) -> Position -> a
paste reg overlay bg coords | reg coords == True = overlay coords
                            | otherwise          = bg coords
带有测试用例的较长版本:

module Image where

type Image a = Position -> a
type Position = (Float, Float) -- [0,1]×[0,1]

data Color = RGB Int Int Int -- Pixels have values in [0,255]×[0,255]×[0,255].
  deriving Show
-- Not efficient for real-world use, but will do for now.

type Region = Image Bool
type ColorImage = Image Color

paste :: Region -> Image a -> Image a -> Image a
-- Is really: (Position->Bool) -> (Position->a) -> (Position->a) -> Position -> a
paste reg overlay bg coords | reg coords == True = overlay coords
                            | otherwise          = bg coords

allRed :: ColorImage
allRed _ = RGB 255 0 0

allWhite :: ColorImage
allWhite _ = RGB 255 255 255

unitCircle :: Region
unitCircle (x,y) = sqrt (x'*x' + y'*y') <= 0.5
  where x' = x - 0.5
        y' = y - 0.5

redCircleOnWhite :: ColorImage
redCircleOnWhite = paste unitCircle allRed allWhite

您可以在REPL中测试redCircleOnWhite。

当您实际参加考试时,这没有什么用处,下面是“教一个人拖网捕鱼”的答案:开始时根本不定义任何结果,让编译器必须是GHC≥7.8对此发表评论。请注意,存根是错误的:如果映像只是一个def类型,则不需要值构造函数映像来匹配它

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会回来的

/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
    ...
好吧,这并不奇怪:我们已经知道结果应该是图像。现在,图像只有一个构造器,也就是图像,所以我们确信我们需要它来构造这样一个图像。仍然对内部实现一无所知:

给予

啊哈,图像中隐藏着一个额外的函数参数!让我们也在这方面进行模式匹配:

paste (Image bol) img1 img2 = Image $ \pos -> _

/tmp/wtmpf-file6644.hs:8:47:
    Found hole ‘_’ with type: a
    ...
好的,a是完全不透明的,所以现在我们可以肯定,没有进一步的信息,我们无能为力。幸运的是,我们有进一步的信息,以论点的形式。GHC将通知您:

    ...
    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)
我们对此无能为力。。。这是很好的,因为这让我们清楚应该做什么:我们可以将pos作为参数提供给bol。结果是Bool类型不同于bol本身,因此它现在是if开关的一个很好的候选者

以前见过,所以我们需要更多的信息。让我们回顾一下这些论点:图像a仍然可以进行模式匹配

paste (Image bol) (Image img1) (Image img2)
  = Image $ \pos -> if bol pos
         then _
         else _
现在它说:

    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)
啊哈,所以img1和img2可以产生我们需要的a值,我们只需要它们首先提供一个位置。嗯,我们还有pos,所以很明显该怎么做:

paste (Image bol) (Image img1) (Image img2)
  = Image $ \pos -> if bol pos
         then img1 pos
         else img2 pos

…或者换了两张照片,你自己想想。但是,实际上没有任何其他定义可以仅使用给定的信息和所有信息编写!,因此,这种类型化的打孔过程是实现函数的一种非常简单的方法。

虽然这在你实际参加考试时没有什么用处,但下面是“教一个人拖网捕鱼”的答案:开始时根本不定义任何结果,让编译器必须是GHC≥7.8对此发表评论。请注意,存根是错误的:如果映像只是一个def类型,则不需要值构造函数映像来匹配它

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会回来的

/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
    ...
好吧,这并不奇怪:我们已经知道结果应该是图像。现在,图像只有一个构造器,也就是图像,所以我们确信我们需要它来构造这样一个图像。仍然对内部实现一无所知:

给予

啊哈,图像中隐藏着一个额外的函数参数!让我们也在这方面进行模式匹配:

paste (Image bol) img1 img2 = Image $ \pos -> _

/tmp/wtmpf-file6644.hs:8:47:
    Found hole ‘_’ with type: a
    ...
好的,a是完全不透明的,所以现在我们可以肯定,没有进一步的信息,我们无能为力。幸运的是,我们 以论点的形式提供进一步的信息。GHC将通知您:

    ...
    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)
我们对此无能为力。。。这是很好的,因为这让我们清楚应该做什么:我们可以将pos作为参数提供给bol。结果是Bool类型不同于bol本身,因此它现在是if开关的一个很好的候选者

以前见过,所以我们需要更多的信息。让我们回顾一下这些论点:图像a仍然可以进行模式匹配

paste (Image bol) (Image img1) (Image img2)
  = Image $ \pos -> if bol pos
         then _
         else _
现在它说:

    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)
啊哈,所以img1和img2可以产生我们需要的a值,我们只需要它们首先提供一个位置。嗯,我们还有pos,所以很明显该怎么做:

paste (Image bol) (Image img1) (Image img2)
  = Image $ \pos -> if bol pos
         then img1 pos
         else img2 pos

…或者换了两张照片,你自己想想。但是,实际上没有任何其他定义可以仅使用给定的信息和所有信息编写!,因此,这种类型化的孔过程是实现函数的一种非常简单的方法。

粘贴只是将值从一个列表复制到另一个列表,如果要检查的区域在image1区域中,请获取该值,否则image1值无法获得该粘贴的功能。为什么它接受图像Bool而不是Bool?粘贴只是将值从一个列表复制到另一个列表中,如果要检查的区域在image1区域中,则应获取该值,否则image1值无法获取粘贴的功能。为什么它接受图像布尔而不是布尔?你如何将图像布尔与真或假匹配?我注意到了。现在修好了。好吧,这似乎管用。希望解释清楚。我不明白你的函数中有什么coords。除此之外,我欣赏您的测试示例。在该示例中,coords是函数的第四个参数,其参数为区域、图像a、图像a和位置。这是一个位置,定义为浮动,浮动。所以,用redCircleOnWhite 0.5,0.5和redCircleOnWhite 1.0,1,0试试。我更改了unitCircle的定义,所以它现在是一个实际的圆,而不是四分之一的圆。如何将图像布尔与真或假匹配?我注意到了。现在修好了。好吧,这似乎管用。希望解释清楚。我不明白你的函数中有什么coords。除此之外,我欣赏您的测试示例。在该示例中,coords是函数的第四个参数,其参数为区域、图像a、图像a和位置。这是一个位置,定义为浮动,浮动。所以,用redCircleOnWhite 0.5,0.5和redCircleOnWhite 1.0,1,0试试。我更改了unitCircle的定义,因此它现在是一个实际的圆,而不是四分之一圆。很好的解释!我想我明白了。谢谢你也展示了这个过程。这是我最初没有得到的模式匹配,但现在我得到了,谢谢。很好的解释!我想我明白了。谢谢你也展示了这个过程。这是我起初没有得到的模式匹配,但现在我得到了,谢谢。