哈斯克尔 - 也许是 [英] Haskell - Maybe Either

查看:212
本文介绍了哈斯克尔 - 也许是的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

   -  |将'Maybe a'转换为等价的'Either()a'。应该将
反转为'UnitToMaybe'。
mayToEitherUnit ::也许a - > ()a
mayToEitherUnit a =

- |将'Either()a'转换为等同的'Maybe a'。应该将
反转为'maybeToEitherUnit'。
orUnitToMaybe :: Either()a - >也许一个
或者unitToMaybe =错误尚未实现:orUnToToMaybe



- |将一对'Bool'和一个'a'转换为'任一a'。应该反转
- 到'eitherToPairWithBool'。
pairWithBoolToEither ::(Bool,a) - > a
pairWithBoolToEither = ...

- |将'a a'转换为一对'Bool'和'a'。应该将
反转为'pairWithBoolToEither'。
orToPairWithBool ::要么是a - > (Bool,a)
orToPairWithBool = ...

- |将函数从'Bool'转换为'a'到一对'a'。应该将
反转为'pairToFunctionFromBool'。
functionFromBoolToPair ::(Bool - > a) - > (a,a)
functionFromBoolToPair =错误尚未实现:functionFromBoolToPair

- |将一对'a'从'Bool'转换为'a'。应该反转
- 到'functionFromBoolToPair'。
pairToFunctionFromBool ::(a,a) - > (Bool - > a)
pairToFunctionFromBool =错误尚未实现:pairToFunctionFromBool

我真的不知道该怎么做。我知道可能是什么,但我认为我也有问题,因为在我的脑海里,一个都没有意义。 或者b 都可以。这是a或b,但是 a a ?!

我一般都不知道如何编写这些函数。

解决方案

鉴于我认为这是作业,我不会回答,但提供重要提示:



如果您在hoogle上查找定义( http://www.haskell。 org / hoogle /
您找到

  data Bool = True |假
数据或者b =左a |正确的b

这意味着 Bool 只能 True False ,但或者ab 都可以留下一个右侧b



这意味着你的函数应该看起来像

  pairWithBoolToEither ::( Bool,a) - > aa 
pairWithBoolToEither(True,a)= ...
pairWithBoolToEither(False,a)= ...

  orToPairWithBool :: aa  - >> (Bool,a)
orToPairWithBool(Left a)= ...
orToPairWithBool(Right a)= ...

可能

也许一个 $ b

 数据给出可能a =只是a | Nothing 

所以类型 Maybe Int 可以是只是7 没有



类型可以是Int Char 可以是左5 右'c'
$ b

类型任何一个Int Int 都可以是 Left 7 code>或右4



因此,类型为 可以是 Int 或者 Char ,但是类型 Int Int 可以是 Int 或者是 Int 。除了 Int 之外,您不会选择其他任何内容,但您会知道它是否是 Left 或a 右键



为什么你一直在问这个问题/ p>

如果您有类型或者aa ,那么数据(例如 5 Left 5 )始终是 a 的类型,并且您用 Left Right 。如果您有类型(Bool,a) a - 数据(例如 5 在(True,5))中始终是相同的类型,并且您已将它与 False True



数学词可能看起来不同,但实际上有相同之处内容是同构的。你的老师让你写一对显示这种同构的功能。如果 pairWithBoolToEither,您的答案会更好。 toToPairWithBool toToPairWithBool。 pairWithBoolToEither 执行 id 的操作,即不改变任何内容。事实上,我刚刚发现了你的问题中的评论,它表示它们应该是反向的。在你的写作中,你应该通过在ghci中进行测试来显示这一点,比如

  ghci>或者ToPairWithBool。 pairWithBoolToEither $(True,'h')
(True,'h')

和反过来。



(如果您没有看到它, $ f $定义x = fx $ 的优先级非常低( infixr 0 $ ),所以< code $ f $ g $ x (f。g)$ x 这就是(f。 g)x 是函数组合,所以(fg)x = f(gx)

接受或返回函数的函数





  functionFromBoolToPair ::(Bool - > a) - > (a,a)

您可以模式匹配函数的唯一方法就是像< code $ f $ f code>,所以我们需要做一些类似于

pre $的函数functionFromBoolToPair f = ...

但我们可以用 f ?那么,给你一个函数最简单的做法就是将它应用到一个值。我们可以使用何种价值 f ?那么 f ::(Bool - > a)所以它需要一个 Bool 并给你一个 a ,所以我们可以做 f真 f False ,它们'会给我们两个(可能是不同的)类型的值 a 。现在,这很方便,因为我们需要 a 值,是不是?



接下来看看

  pairToFunctionFromBool ::(a,a) - > (Bool  - > a)

我们可以为类型(a,a)类似于(x,y),所以我们需要

  pairToFunctionFromBool(x,y)= .... 

但是我们怎么能在右边返回一个函数(Bool - > a)



我认为你会发现最简单的方法有两种。其中一个要注意的是,既然 - > 无论如何都是正确关联的,类型(a,a) - > (Bool - > a)(a,a) - >相同。布尔 - >一个,所以我们实际上可以将我们想返回的函数的参数移动到=符号之前,如下所示:

  pairToFunctionFromBool(x,y)True = ... 
pairToFunctionFromBool(x,y)True = ...

另一种感觉也许更简单的方法是使 let ,其中子句来定义一个称为类似于 f 的函数,其中 f :: Bool - >一个<有点像:

  pairToFunctionFromBool(x,y)= f其中
f True = ....
f False = ....

玩得开心。乱七八糟。


    -- | Convert a 'Maybe a' to an equivalent 'Either () a'. Should be inverse
    -- to 'eitherUnitToMaybe'.
    maybeToEitherUnit :: Maybe a -> Either () a
    maybeToEitherUnit a =  

    -- | Convert a 'Either () a' to an equivalent 'Maybe a'. Should be inverse
    -- to 'maybeToEitherUnit'.
    eitherUnitToMaybe :: Either () a -> Maybe a     
    eitherUnitToMaybe = error "Not yet implemented: eitherUnitToMaybe"   



-- | Convert a pair of a 'Bool' and an 'a' to 'Either a a'. Should be inverse
        -- to 'eitherToPairWithBool'.
        pairWithBoolToEither :: (Bool,a) -> Either a a
        pairWithBoolToEither = ...

    -- | Convert an 'Either a a' to a pair of a 'Bool' and an 'a'. Should be inverse
    -- to 'pairWithBoolToEither'.
    eitherToPairWithBool :: Either a a -> (Bool,a)
    eitherToPairWithBool = ...

-- | Convert a function from 'Bool' to 'a' to a pair of 'a's. Should be inverse
-- to 'pairToFunctionFromBool'.
functionFromBoolToPair :: (Bool -> a) -> (a,a)
functionFromBoolToPair = error "Not yet implemented: functionFromBoolToPair"

-- | Convert a pair of 'a's to a function from 'Bool' to 'a'. Should be inverse
-- to 'functionFromBoolToPair'.
pairToFunctionFromBool :: (a,a) -> (Bool -> a)
pairToFunctionFromBool = error "Not yet implemented: pairToFunctionFromBool"

I don't really know what to do. I know what maybe is, but I think I have a problem with either, because Either a a makes no sense in my mind. Either a b would be okay. This is either a or b but Either a a is a?!

I don't have any idea in general how to write these functions.

解决方案

Given that I think this is homework, I'll not answer, but give important hints:

If you look for the definitions on hoogle (http://www.haskell.org/hoogle/) you find

data Bool = True | False
data Either a b = Left a | Right b

This means that Bool can only be True or False, but that Either a b can be Left a or Right b.

which means your functions should look like

pairWithBoolToEither :: (Bool,a) -> Either a a
pairWithBoolToEither (True,a) = ....
pairWithBoolToEither (False,a) = ....

and

eitherToPairWithBool :: Either a a -> (Bool,a)
eitherToPairWithBool (Left a) = ....
eitherToPairWithBool (Right a) = ....

Comparing with Maybe

Maybe a is given by

data Maybe a = Just a | Nothing

so something of type Maybe Int could be Just 7 or Nothing.

Similarly, something of type Either Int Char could be Left 5 or Right 'c'.

Something of type Either Int Int could be Left 7 or Right 4.

So something with type Either Int Char is either an Int or a Char, but something of type Either Int Int is either an Int or an Int. You don't get to choose anything other than Int, but you'll know whether it was a Left or a Right.

Why you've been asked this/thinking behind it

If you have something of type Either a a, then the data (eg 5 in Left 5) is always of type a, and you've just tagged it with Left or Right. If you have something of type (Bool,a) the a-data (eg 5 in (True,5)) is always the same type, and you've paired it with False or True.

The maths word for two things which perhaps look different but actually have the same content is "isomorphic". Your instructor has asked you to write a pair of functions which show this isomorphism. Your answer will go down better if pairWithBoolToEither . eitherToPairWithBool and eitherToPairWithBool . pairWithBoolToEither do what id does, i.e. don't change anything. In fact, I've just spotted the comments in your question, where it says they should be inverses. In your write-up, you should show this by doing tests in ghci like

ghci> eitherToPairWithBool . pairWithBoolToEither $ (True,'h')
(True,'h')

and the other way round.

(In case you haven't seen it, $ is defined by f $ x = f x but $ has really low precedence (infixr 0 $), so f . g $ x is (f . g) $ x which is just (f . g) x and . is function composition, so (f.g) x = f (g x). That was a lot of explanation to save one pair of brackets!)

Functions that take or return functions

This can be a bit mind blowing at first when you're not used to it.

functionFromBoolToPair :: (Bool -> a) -> (a,a)

The only thing you can pattern match a function with is just a variable like f, so we'll need to do something like

functionFromBoolToPair f = ...

but what can we do with that f? Well, the easiest thing to do with a function you're given is to apply it to a value. What value(s) can we use f on? Well f :: (Bool -> a) so it takes a Bool and gives you an a, so we can either do f True or f False, and they'll give us two (probably different) values of type a. Now that's handy, because we needed to a values, didn't we?

Next have a look at

pairToFunctionFromBool :: (a,a) -> (Bool -> a)

The pattern match we can do for the type (a,a) is something like (x,y) so we'll need

pairToFunctionFromBool (x,y) = ....

but how can we return a function (Bool -> a) on the right hand side?

There are two ways I think you'll find easiest. One is to notice that since -> is right associative anyway, the type (a,a) -> (Bool -> a) is the same as (a,a) -> Bool -> a so we can actually move the arguments for the function we want to return to before the = sign, like this:

pairToFunctionFromBool (x,y) True = ....
pairToFunctionFromBool (x,y) True = ....

Another way, which feels perhaps a little easier, would to make a let or where clause to define a function called something like f, where f :: Bool -> a< a bit like:

pairToFunctionFromBool (x,y) = f where
  f True = ....
  f False = ....

Have fun. Mess around.

这篇关于哈斯克尔 - 也许是的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆