在Haskell中,如果我创建这样的数据表:
data MyT = MyT Int deriving (Show)
myValue = MyT 42
我可以获取Int值,将'myValue'传递给函数并进行模式匹配:
getInt :: MyT -> Int
getInt (MyT n) = n
在我看来,更简单的事情应该是可能的。还有另一种方式吗?
另外,我尝试了一个lambda函数:
(\(MyT n) -> n) myValue
它不起作用,我不明白为什么不。 我收到错误:
The function `\ (MyT n) -> n' is applied to two arguments, but its type `MyT -> Int' has only one
修改 当然,下面的sepp2k,对我的lambda函数工作正常。我在做:
(\(MyT n) -> n) myT 42
而不是
(\(MyT n) -> n) (myT 42)
答案 0 :(得分:3)
如果你想在没有定义辅助函数的情况下在更大的函数中获取MyT的值,你可以在局部变量定义中使用case of
或模式匹配。以下是此示例(假设g
生成MyT
而f
生成Int
):
使用case
:
myLargerFunction x = f (case g x of MyT n => n)
或使用局部变量:
myLargerFunction x = f myInt
where MyT myInt = g x
或使用let
代替where
:
myLargerFunction x =
let MyT myInt = g x in
f myInt
你的lambda函数应该(实际上)也可以正常工作。您的错误消息表明,在您的真实代码中,您实际上正在执行类似(\(MyT n) -> n) myValue somethingElse
的操作(可能是偶然的)。
答案 1 :(得分:3)
您可以使用记录语法
data MyT = MyT {unMyT :: Int} deriving (Show)
为您提供免费投影
unMyT :: MyT -> Int
如果您的数据类型只有一个构造函数(包括newtype
s),这很好。对于涉及多个constrctor的数据类型,投影函数往往是不安全的(例如,head
,tail
),并且通常首选模式匹配。如果启用警告,GHC会检查非详尽模式,并可帮助发现错误。
答案 2 :(得分:2)
NewTypes创建一个不同的类型,并且没有额外的间接级别,如代数数据类型。有关更多信息,请参阅Haskell报告:
http://www.haskell.org/onlinereport/decls.html#sect4.2.3
Prelude> newtype Age = Age { unAge :: Int } deriving (Show)
Prelude> let personAge = Age 42
Prelude> personAge
Age {unAge = 42}
Prelude> (unAge personAge) + 1
43
使用lambda函数:
Prelude> (\(Age age) -> age * 2) personAge
84