当型X定义为:

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

和我想要一个Int值内的X,如果有一个,否则为零。

returnInt :: X -> Int

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

有帮助吗?

解决方案

就在这里澄清一点,让我重写你的数据类型,以避免X的含义含糊:

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

在此定义不存在X,I和B类型。 X,I和B是创建类型 Sometype的值的构造。注意:当你问ghci的是什么这些类型构造建造的任何值的类型会发生什么:

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

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

它们属于相同类型!!

正如可以使用X,I和B来构造类型,可以使用模式匹配来解构的类型,像在其他的答案进行以上:

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
发生在顺序

只要记住,模式匹配:如果该值在一些行中的图案相匹配,在低于该线的图案将不会被执行

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

尝试寻找上明特的类型,例如:

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

和看一下这个功能做的:

*Main> myInt (I 5)
5

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

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

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

data SomeType2 = X String | I Int | B Bool

然后你松那些好的记录功能。

在错误消息终止程序的执行。这是烦人有时。如果您需要更安全的行为为您的功能GBacon的回答仅仅是做到这一点。了解Maybe a类型,并用它来应付这种计算需要返回一些值,或者什么也不返回(试试这个:的 http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe )。

其他提示

使用模式匹配。

returnInt :: X -> Int
returnInt (I x) = x
returnInt _     = 0

使用更灵活的定义为所有可能的X值:

returnInt :: X -> Maybe Int
returnInt (I i) = Just i
returnInt _ = Nothing

然后可以使用 maybe 对特定违约想要-0可能是一个有效的值(这是被称为 semipredicate问题):

*Main> maybe 0 id (returnInt $ X "")
0
*Main> maybe 0 id (returnInt $ I 123)
123
*Main> maybe (-1) id (returnInt $ X "yo")
-1

在另一方面,部分功能风险运行时异常:

*Main> let returnInt (I i) = i
*Main> :t returnInt
returnInt :: X -> Int
*Main> returnInt (B True)
*** Exception: <interactive>:1:4-22: Non-exhaustive patterns in function returnInt

如果你感觉真的小青蛙,你可以使用MonadPlus

returnInt :: (MonadPlus m) => X -> m Int
returnInt (I i) = return i
returnInt _ = mzero

,以获得更大的灵活性:

*Main> maybe 0 id (returnInt $ X "")
0
*Main> maybe 0 id (returnInt $ I 123)
123
*Main> returnInt (I 123) `mplus` returnInt (I 456) :: [Int]
[123,456]

给定一个功能是这样的:

returnInt :: X -> Int
returnInt x = {- some integer -}

... x的类型总是X。你关心什么是x是否使用XIB类型构造。

使用模式匹配来分辨:

returnInt :: X -> Int
returnInt (X _) = error "needed an Int, got a String"
returnInt (I { iVal = n }) = n
returnInt (B _) = error "needed an Int, got a Bool"
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top