在Haskell代数数据类型中选择替代方案 [英] Choosing among alternatives in a Haskell algebraic datatype

查看:160
本文介绍了在Haskell代数数据类型中选择替代方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当键入 X 被定义为:

data X = 
    X { sVal :: String } |
    I { iVal :: Int } |
    B { bVal :: Bool }

我想要如果有一个,否则为零, X 中的Int

and I want the Int inside an X value, if there is one, otherwise zero.

returnInt :: X -> Int

如何确定哪种类型的 X returnInt 的参数是?

How can I determine which type of X the argument to returnInt is?

推荐答案

只是为了澄清一点这里,让我重写你的数据类型,以避免含义X:

Just to clarify a point here, let me rewrite your data type to avoid ambiguities in the meaning of X:

data SomeType = X { myString :: String} | I {myInt :: Int} | B {myBool :: Bool}

在这个定义中,没有X,I和B类型。 X,I和B是构造函数,它们创建一个类型为 Sometype 的值。请注意,当您问ghci时,使用这些类型构造函数构造的任何值的类型是什么?

In this definition there are no X, I and B types. X, I and B are constructors that create a value of type Sometype . Note what happens when you ask ghci what is the type of any value constructed with those type constructors:

*Main> :t (I 5)
(I 5) :: Sometype 

*Main> :t (B False)
(B False) :: Sometype

他们属于同样的类型!!

They belong to the same type!!

正如您可以使用X,I和B构造类型一样,您可以使用模式匹配来解构类型,就像在上面的其他答案中所做的那样:

Just as you can use X, I and B to construct types, you can use pattern matching to deconstruct the type, like done in the other answers above:

returnInt :: SomeType -> Int 
returnInt (I x) = x        -- if the pattern matches (I x) then return x
returnInt _  = error "I need an integer value, you moron"  -- throw an error otherwise

请记住,模式匹配按顺序发生:如果值与某行中的模式匹配,则下面的行将不会执行。

Just remember that pattern matching occurs in order: if the value matches the pattern in some line, the patterns in lines below that will not be executed.

请注意,当您像您一样定义类型时,使用所谓的记录语法(只需看看这里: http://en.wikibooks.org/wiki/Haskell/More_on_datatypes ),你有这样的功能免费!!

Note that when you define your type like you did, using what is called Record Syntax (just look here: http://en.wikibooks.org/wiki/Haskell/More_on_datatypes ), you got functions like that for free!!

尝试查看myInt的类型,例如:

Try looking on the type of myInt, for example:

*Main> :t myInt
myInt :: SomeType -> Int

看看这个函数做什么:

*Main> myInt (I 5)
5

*Main> myInt (B False)
*** Exception: No match in record selector Main.myInt

这正是上述定义的 returnInt 的行为。奇怪的错误消息只是告诉你,该函数不知道如何处理与(I x)不匹配的SomeType类型的成员。

This is exactly the behavior of returnInt above defined. The strange error message just tells you that the function don't know how to deal with a member of the type SomeType that doesn't match (I x).

如果您使用更常见的语法定义类型:

If you define your type using the more common syntax:

data SomeType2 = X String | I Int | B Bool

然后你会丢失那些好的记录功能。

then you loose those nice record functions.

错误消息终止程序的执行。这有时候很讨厌如果您需要更安全的行为,您的功能,GBacon的答案就是这样做。了解可能是一个类型,并使用它来处理这种需要返回一些值或不返回任何内容的计算(尝试这样: http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe )。

The error messages terminate the execution of the program. This is annoying sometimes. If you need safer behavior for your functions GBacon's answer is just the way to do it. Learn about the Maybe a type and use it to cope with this kind of computation that need to return some value or return nothing ( try this: http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe ).

这篇关于在Haskell代数数据类型中选择替代方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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