-- | Convert a 'Maybe a' to an equivalent 'Either () a'. Should be inverse
-- to 'eitherUnitToMaybe'.
maybeToEitherUnit :: Maybe a -> Either () a
maybeToEitherUnit a = error "Not yet implemented: maybeToEitherUnit"
-- | 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 = undefined -- What should I do here?
-- | 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 = undefined -- What should I do here?
-- | 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"
Run Code Online (Sandbox Code Playgroud)
我真的不知道该怎么做.我知道可能是什么,但我认为我也遇到了问题,因为Either a a在我看来没有任何意义.Either a b没关系.这是A或B,但Either a a是a?!
我一般不知道如何编写这些函数.
And*_*ewC 15
鉴于我认为这是家庭作业,我不会回答,但给出重要提示:
如果你在hoogle(http://www.haskell.org/hoogle/)上寻找定义,你会发现
data Bool = True | False
data Either a b = Left a | Right b
Run Code Online (Sandbox Code Playgroud)
这意味着Bool只能是True或False,但Either a b可以是Left a或Right b.
这意味着你的功能应该是这样的
pairWithBoolToEither :: (Bool,a) -> Either a a
pairWithBoolToEither (True,a) = ....
pairWithBoolToEither (False,a) = ....
Run Code Online (Sandbox Code Playgroud)
和
eitherToPairWithBool :: Either a a -> (Bool,a)
eitherToPairWithBool (Left a) = ....
eitherToPairWithBool (Right a) = ....
Run Code Online (Sandbox Code Playgroud)
比较 Maybe
Maybe a 是(谁)给的
data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)
所以类型Maybe Int可能是Just 7或Nothing.
同样,某种类型Either Int Char可能是Left 5或Right 'c'.
某种类型Either Int Int可能是Left 7或Right 4.
所以类型的东西Either Int Char要么是Inta Char,要么是a ,但类型的东西Either Int Int要么是a Int还是a Int.你不能选择除了之外的任何东西Int,但你会知道它是a Left还是a Right.
为什么你被问到/背后的想法
如果你有类型的东西Either a a,那么数据(例如5in Left 5)总是类型的a,你只是用Left或标记它Right.如果你有类型(Bool,a)的东西 - a-data(例如5in (True,5))总是相同的类型,并且你已经将它与Falseor 配对True.
两个可能看起来不同但实际上具有相同内容的事物的数学词是"同构的".你的导师要求你写一对显示这种同构的函数.你的回答会下降,如果更好的pairWithBoolToEither . eitherToPairWithBool和eitherToPairWithBool . pairWithBoolToEither做什么id呢,即不改变任何东西.事实上,我刚刚在你的问题中发现了这些评论,它说它们应该是逆向的.在你的写作中,你应该通过在ghci中进行测试来证明这一点
ghci> eitherToPairWithBool . pairWithBoolToEither $ (True,'h')
(True,'h')
Run Code Online (Sandbox Code Playgroud)
反之亦然.
(如果你还没有看到它,$被定义的f $ x = f x,但$具有非常低的优先级(infixr 0 $),所以f . g $ x是(f . g) $ x这仅仅是(f . g) x和.是函数组合,所以(f.g) x = f (g x),这是一个很多的解释,以节省一对括号!)
当你不习惯它时,这可能有点令人兴奋.
functionFromBoolToPair :: (Bool -> a) -> (a,a)
Run Code Online (Sandbox Code Playgroud)
你可以模式匹配函数的唯一的东西就是变量f,所以我们需要做类似的事情
functionFromBoolToPair f = ...
Run Code Online (Sandbox Code Playgroud)
但我们能做些什么f呢?那么,使用函数最简单的方法就是将它应用于一个值.我们可以使用什么价值f?那么f :: (Bool -> a)它需要一个Bool并给你一个a,所以我们可以做f True或者f False,他们会给我们两个(可能是不同的)类型的值a.现在这很方便,因为我们需要a价值观,不是吗?
接下来看看
pairToFunctionFromBool :: (a,a) -> (Bool -> a)
Run Code Online (Sandbox Code Playgroud)
我们可以为类型做的模式匹配(a,a)就像(x,y)我们需要的那样
pairToFunctionFromBool (x,y) = ....
Run Code Online (Sandbox Code Playgroud)
但是我们如何才能(Bool -> a)在右侧返回一个功能呢?
有两种方法我认为你会发现最简单的方法.一个是要注意,因为->无论如何都是右关联,类型(a,a) -> (Bool -> a)是相同的,(a,a) -> Bool -> a所以我们实际上可以移动我们想要在=符号之前返回的函数的参数,如下所示:
pairToFunctionFromBool (x,y) True = ....
pairToFunctionFromBool (x,y) False = ....
Run Code Online (Sandbox Code Playgroud)
另一种感觉可能稍微容易一点的方法是创建一个let或者where子句来定义一个叫做类似的函数f,其中f :: Bool -> a有点像:
pairToFunctionFromBool (x,y) = f where
f True = ....
f False = ....
Run Code Online (Sandbox Code Playgroud)
玩得开心.乱来的.
也许有用的是要注意它Either a b也被称为类型和的副产品或总和.实际上现在常用ab
type (+) = Either
Run Code Online (Sandbox Code Playgroud)
然后你可以写Either a b为a + b.
eitherToPairWithBool :: (a+a) -> (Bool,a)
Run Code Online (Sandbox Code Playgroud)
现在,常识会要求我们重写a + a为类似的东西2 ? a.信不信由你,这正是你正在转变的元组类型的意义!
解释:代数数据类型大致可以看作是"计算1可能结构的数量".所以
data Bool = True | False
Run Code Online (Sandbox Code Playgroud)
有两个构造函数.所以(这不是有效的Haskell!)
type 2 = Bool
Run Code Online (Sandbox Code Playgroud)
元组允许来自每个参数的构造函数的所有组合.所以例如(Bool, Bool),我们有价值观
(False,False)
(False,True )
(True, False)
(True, True )
Run Code Online (Sandbox Code Playgroud)
你已经猜到了:元组也被称为产品.所以类型(Bool, a)基本上是2 ? a:对于每个值x :: a,我们可以创建(False, x)元组和(True, x)元组,总共是x值的两倍.
同样的事情Either a a:我们总是同时拥有Left x和Right x作为可能的价值.
type OnePlus = Maybe
maybeToEitherUnit :: OnePlus a -> () + a
eitherUnitToMaybe :: () + a -> OnePlus a
pairWithBoolToEither :: 2 ? a -> a + a
eitherToPairWithBool :: a + a -> 2 ? a
functionFromBoolToPair :: a² -> a?a
pairToFunctionFromBool :: a?a -> a²
Run Code Online (Sandbox Code Playgroud)
1 对于几乎任何有趣的类型,实际上存在无限多的可能值,但这种天真的算法仍然让你惊讶不已.
| 归档时间: |
|
| 查看次数: |
3642 次 |
| 最近记录: |