标签: pattern-matching

如何将这种 if-then-else 结构更改为使用模式匹配或/和防护的结构?

我进行了以下练习(链接在一起以漂亮地打印表格并在其中进行选择的几个练习之一):

\n
\n

编写一个函数 select :: Field \xe2\x86\x92 Field \xe2\x86\x92 Table \xe2\x86\x92 给定列名和字段值的表,仅从表中选择具有给定字段的行给定列中的值。如果给定的列不存在于表中,则表应原样返回。(提示:使用函数 (!!)、elemIndex、filter 等。)

\n
\n

最终得到了这个解决方案:

\n
select :: Field -> Field -> Table -> Table\nselect column value table@(header:rows) =\n    let i = fromMaybe (-1) (elemIndex column header)\n    in  if i == (-1) then table\n        else header : filter (\\r -> r !! i == value) rows\n
Run Code Online (Sandbox Code Playgroud)\n

虽然它的功能似乎完全正确 - 它有效 - 我被告知 if-then-else 结构(例如这些)是“坏形式”,应该避免使用防护(就像我使用 fromMaybe 使用模式匹配一​​样) )。

\n

我将如何通过模式匹配/防护将其更改为“更好”的样式?

\n

haskell function list pattern-matching

1
推荐指数
1
解决办法
114
查看次数

在 OCaml 中如何在保留变量名称的同时模式匹配函数参数

我有一些代码:

let some_func some_arg = (* ... *)
Run Code Online (Sandbox Code Playgroud)

some_arg真正需要的地方[| arg1; arg2 |]。我想在函数参数位置进行模式匹配,例如:

let some_func [| arg1; arg2 |] = (* ... *)
Run Code Online (Sandbox Code Playgroud)

但我也想保留变量名称some_arg,以防我想直接用它做一些事情。我怎样才能做到这一点?

ocaml pattern-matching

1
推荐指数
1
解决办法
476
查看次数

java中模式变量的范围是如何解析的?

我正在研究java中的模式变量。在阅读JLS时,它提到了有关何时引入模式变量的几个条件。它提到——

该分析依赖于技术术语“introduced by”,其形式如下:

  • 当 true 时,模式变量表达式引入
  • 当 false 时,模式变量表达式引入
  • 模式变量语句引入

在 6.3.1 中提到了表达式中模式变量的范围,其中指出何时为&&||!?:等引入模式变量。

但我觉得解释很混乱,谁能详细说明一下&&,,||!

模式变量的示例 -

Object o = "a";

if(o instanceof String s) {
    System.out.println(s); 
}
Run Code Online (Sandbox Code Playgroud)

我困惑的地方——

class foo {
    String s, n, p, m;

    void method() {
        Object o = "s";
        if (!(o instanceof Integer s) && o instanceof Integer n) {
            System.out.println(s + " " …
Run Code Online (Sandbox Code Playgroud)

java pattern-matching jls java-14

1
推荐指数
1
解决办法
970
查看次数

非构造函数的模式匹配

模式匹配和惰性求值结合在一起的最强大方法之一是绕过昂贵的计算。然而,我仍然感到震惊的是,Haskell 只允许构造函数的模式匹配,这根本就不是模式匹配!

有没有办法在 Haskell 中实现以下功能:

exp :: Double -> Double
exp 0 = 1
exp (log a) = a
--...

log :: Double -> Double
log 1 = 0
log (exp a) = a
--...
Run Code Online (Sandbox Code Playgroud)

我发现这很有用的最初问题是在 Monoid 类中编写关联性首选项/规则:

class Monoid m where
  iden :: m
  (+) m -> m -> m

  (+) iden a = a
  (+) a iden = a

  --Line with issue
  (+) ((+) a b) c = (+) a ((+) b c)
Run Code Online (Sandbox Code Playgroud)

language-features haskell pattern-matching

1
推荐指数
1
解决办法
145
查看次数

在 Haskell 中更优雅地表达“case ... of”模式

我发现了一种我认为可以更优雅地表达的模式:

我有两个函数f1,f2 :: Int -> Int(它们的实现不相关),以及一个process :: Int -> Int执行以下操作的函数:

  • 如果f1 x产生的结果x1与 不同x,则重复该过程x1
  • 否则,如果f2 x产生的结果x2与 不同x,则重复该过程x2
  • 最后,停止进程并返回x

我的case ... of实现如下:

f1 :: Int -> Int
f1 = undefined

f2 :: Int -> Int
f2 = undefined

process :: Int -> Int
process x =
    case f1 x of
        x ->
            case f2 x of
                x -> x
                x' -> …
Run Code Online (Sandbox Code Playgroud)

haskell pattern-matching fixed-point-iteration

1
推荐指数
2
解决办法
1447
查看次数

为什么 ["",_] 与 ("":_) 不同?

我偶然发现了一个令我非常困惑的错误。我有一个带有模式匹配的递归函数,["",_] = []但它根本不起作用。经过多次尝试找出我的错误后,我尝试将其与("":_) = []. 它成功了!我只是想知道为什么第一个术语不起作用但第二个术语起作用。该函数起作用并调用模式匹配:

takeAllElem :: [String] -> [String]
takeAllElem ("":_) = []
takeAllElem (xs) =  map takeFirstElem (xs) :  (takeAllElem (removeFirstElem (xs)))
Run Code Online (Sandbox Code Playgroud)

这个函数也可以工作,但是模式匹配永远不会被调用:

takeAllElem :: [String] -> [String]
takeAllElem ["",_] = []
takeAllElem (xs) =  map takeFirstElem (xs) :  (takeAllElem (removeFirstElem (xs)))
Run Code Online (Sandbox Code Playgroud)

这只是一个语法错误还是编译器的解释["",_]("":_).

haskell pattern-matching

1
推荐指数
1
解决办法
76
查看次数

如何读取 Haskell 中二叉树中的内容?

我有以下类型:

data Tree = Branch (Tree) (Tree) | Leaf Int deriving(Show)
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个函数来给出树中最高值的叶子。但我被困住了,因为我不知道如何获取给定树的以下两棵树。

例如我有一棵树 a 看起来像这样:let a = Branch (Leaf 10) (Leaf 2)

如何读取10另一个函数中具有值的叶子?

recursion haskell pattern-matching

1
推荐指数
2
解决办法
118
查看次数

scala 类型擦除 - 匹配案例类

我正在阅读有关类型擦除的内容,在这里

case class Thing[T](value: T)

def processThing(thing: Thing[_]) = {
  thing match {
    case Thing(value: Int) => "Thing of int"         //isn't thing Thing[_] anymore?
    case Thing(value: String) => "Thing of string"   //isn't thing Thing[_] anymore?
    case Thing(value: Seq[Int]) => "Thing of Seq[Int]"         //value=Seq[_] really
    case Thing(value: Seq[String]) => "Thing of Seq[String]"   //value=Seq[_] really
    case _ => "Thing of something else"
  }
}
println(processThing(Thing(Seq(1,2,3))))          //type erased, I get it
println(processThing(Thing(Seq("hello", "yo"))))  //type erased, I get it
println(processThing(Thing(1)))                   //why is this …
Run Code Online (Sandbox Code Playgroud)

scala pattern-matching type-erasure

1
推荐指数
1
解决办法
344
查看次数

功能中的非详尽模式 - Maybe 类型

在下面的函数定义中,我在函数 tapChar 中得到了非详尽模式。

我缺少什么?

reverseTap :: DaPhone -> Char -> [(Digit, Presses)]
reverseTap phone s 
    | isUpper s  = ('*',1) : tapChar (toLower s) phone
    | otherwise = tapChar s phone
    where tapChar s (DaPhone[buttons]) = map (\x -> case (elemIndex s $ phChar x) of
                                         (Just i)  ->  (digit x , i)
                                         Nothing   ->  (' ', (-1))) [buttons]
          phChar (Button _ chars) = chars
          digit  (Button d _)     = d
Run Code Online (Sandbox Code Playgroud)

haskell pattern-matching where-clause option-type

1
推荐指数
1
解决办法
142
查看次数

了解 Coq 中模式匹配的工作原理

我目前正在关注《软件基础》一书,目前正在阅读“列表”章节。 然而,我很难理解模式匹配的具体情况,并且由于是 Coq 的初学者,我不确定如何找到这个问题的答案。

因此,练习是创建一个来计算列表(更具体地说是一个包)中有Fixpoint多少 nat 。vs

我决定为此使用模式匹配,但如果我尝试定义这样的函数:

Fixpoint count' (v: nat) (s: bag) : nat :=
  match s with
  | nil => O
  | h :: t => match h with
              | v => S (count' v t)
              end
  end.
Run Code Online (Sandbox Code Playgroud)

并尝试将此功能应用于,比方说,

Example test_count1: count' 1 [1;2;3;1;4;1] = 3.
Run Code Online (Sandbox Code Playgroud)

我最终会得到6 = 3。我的理解是,匹配h始终v是“true”,因此它最终会计算列表中的每个元素。

但为什么会发生这种情况呢?h我们如何使用模式匹配来比较和的值v

PS:我已经使用比较 ifhvequal 的辅助函数解决了这个练习,但我想知道这是否只能使用内置模式匹配来实现。

pattern-matching coq

1
推荐指数
1
解决办法
164
查看次数