得到了这个:
data Cmd = PushK Int | Pop | Push Int
deriving (Eq,Show)
type StackProgram = [Cmd]
问题:
如何访问Int
的{{1}}值?
PushK
任何人都有解决方案吗?
答案 0 :(得分:4)
使用模式匹配或通过定义记录语法(在这种情况下Haskell自己生成getter)来从数据构造函数中取出值。
由于此类型不定义为记录,因此我们必须使用模式匹配:
getK :: Cmd -> Int
getK (PushK x) = x
-- ...
可能你需要处理另一个数据构造函数的情况。
我们也可以使用lambda表达式执行此模式匹配:
(\(PushK x) -> x) (PushK 5)
我们还可以将命令定义为记录:
data Cmd = PushK { k :: Int } | Pop | Push { p :: Int } deriving (Eq,Show)
现在Haskell自动生成了两个函数k :: Cmd -> Int
和p :: Cmd -> Int
,所以在这种情况下我们可以写:
k (PushK 5)
将返回5
。
(\_ x -> x) PushK 5
会返回5
?在Haskell中,函数是一等公民。这意味着您可以将函数作为参数传递,并将其作为结果返回。你在这里不构建了一个Cmd
。
实际上PushK
是一个数据构造函数和一个函数(类型为Int -> Cmd
),因此你用两个调用了lambda表达式参数:第一个是pushK
,第二个是5
。您只需省略第一个参数,然后重新调整第二个x
。
但它因此得出:
(\y x -> x) PushK 5
= ((\y -> (\x -> x)) PushK) 5 -- (more verbose version)
-> (\x -> x) 5
-> 5
答案 1 :(得分:1)
您可能希望定义一个 catamorphism 来解构任意Cmd
值。
cmdCata :: (Int -> a) -- Function to apply to x in (PushK x)
-> a -- Value to replace Pop
-> (Int -> a) -- Function to apply to x in (Push x)
-> Cmd -- The value to deconstruct
-> a -- The result
cmdCata f _ _ (PushK x) = f x
cmdCata _ x _ Pop = x
cmdCata _ _ f (Push x) = f x
它需要两个函数和一个默认值(对于Pop
)将任何 Cmd
值转换为a
类型的值。以下内容提取PushK
或Push
包含的值,并使用Just
对其进行重新处理(PushK
的函数执行一些额外的工作,以显示{{1}之间的差异}和PushK
),并将Push
替换为Pop
。
Nothing
或者,如果您只想要一个整数,> cmdCata (Just . (+3)) Nothing Just (PushK 5)
Just 8 -- 5 + 3
> cmdCata (Just . (+3)) Nothing Just Pop
Nothing
> cmdCata (Just . (+3)) Nothing Just (Push 20)
Just 20
的默认值就可以了:
Pop
将> cmdCata id 0 id (PushK 5)
5
> cmdCata id 0 id Pop
0
> cmdcata id 0 id (Push 3)
3
与cmdCata
进行比较,并考虑可以为Data.Maybe.maybe
类型定义与Data.Maybe.fromJust
,Data.Maybe.catMaybes
等类似的功能。< / p>