Haskell - 在模式匹配中使用常量 [英] Haskell - Using a constant in pattern matching

查看:125
本文介绍了Haskell - 在模式匹配中使用常量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下代码(<> 中的文字是简写,实际上不是代码的一部分):

  data A =< something> 
defaultA :: A
defaultA =<真正复杂的A型表达>

现在我想在 defaultA ,如下所示:

  f defaultA =< case 1> 
f _ =<案例2>

然而,第一行中的 defaultA 变成一个新变量,而不是一个条件,意味着该参数将等于 defaultA 。我知道实现类似我想要的最好方式是:
$ b $ pre $ f x | x == defaultA =< case 1>
f _ =<案例2>

有人知道更好的方法吗?

defaultA 的定义仅包含构造函数调用,那么可以使用 pattern synonym

  { - #LANGUAGE PatternSynonyms# - } 

data A = A Int

模式DefaultA = A 3

isDefaultA DefaultA = putStrLn它是一个默认的
isDefaultA _ = putStrLn它不是默认的

不过,这并不是一个特别习惯的部署 PatternSynonyms 。我可能会坚持使用Haskell 98,使用一个稍微更冗长的guard条款与平等测试。

  data A =一个Int推导出Eq 

defaultA = A 3

isDefaultA a
|一个== defaultA = putStrLn它是一个默认的
|否则= putStrLn它不是默认的






在模式同义词 do 中有用的是用于包装当您执行数据类型时强加给您的噪声库构造函数调用 - 使用诸如 free monads 单点菜单数据类型

  { - #LANGUAGE PatternSynonyms# - } 
{ - #LANGUAGE TypeOperators# - }

- 函子的固定点
newtype Expr f = In(f(Expr f))

- 函子副产品
数据(f:+:g)a = Inl (fa)| Inr(ga)


- 现在插入自定义代码
数据添加r = Add_ rr
数据Val r = Val_ Int
类型HuttonsRazor = Expr(Add:+:Val)

pattern添加xy = In(Inl(Add_ xy))
模式Val x = In(Inr(Val_ x))

eval :: HuttonsRazor - > Int
eval(Add x y)= eval x + eval y
eval(Val x)= x


Let's say I have the following code (text in <> is a shorthand, not actually part of the code):

data A = <something>
defaultA :: A
defaultA = <Really complicated expression of type A>

Now I want to have a function pattern match on defaultA, like this:

f defaultA = <case 1>
f _ = <case 2>

However, defaultA in the first line becomes a new variable, not a condition that means the parameter will equal defaultA. The best way I know to achieve something like what I want is:

f x | x == defaultA = <case 1>
f _ = <case 2>

Does anyone know a better way?

解决方案

If the definiton of defaultA consists only of constructor calls, you could use a pattern synonym.

{-# LANGUAGE PatternSynonyms #-}

data A = A Int

pattern DefaultA = A 3

isDefaultA DefaultA = putStrLn "it was a default"
isDefaultA _ = putStrLn "it was not a default"

This isn't a particularly idiomatic deployment of PatternSynonyms though. I'd probably stick with Haskell 98, using a very-slightly-more-verbose guard clause with an equality test.

data A = A Int deriving Eq

defaultA = A 3

isDefaultA a
    | a == defaultA = putStrLn "it was a default"
    | otherwise = putStrLn "it was not a default"


Where pattern synonyms do come in useful is for wrapping up noisy library constructor calls imposed on you when you're doing datatype-generic programming with a pattern like free monads or Data Types a la Carte.

{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeOperators #-}

-- fixed point of functor
newtype Expr f = In (f (Expr f))

-- functor coproduct
data (f :+: g) a = Inl (f a) | Inr (g a)


-- now plug in custom code
data Add r = Add_ r r
data Val r = Val_ Int
type HuttonsRazor = Expr (Add :+: Val)

pattern Add x y = In (Inl (Add_ x y))
pattern Val x = In (Inr (Val_ x))

eval :: HuttonsRazor -> Int
eval (Add x y) = eval x + eval y
eval (Val x) = x

这篇关于Haskell - 在模式匹配中使用常量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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