actfromAnd
每当我运行代码时,iframe
和let disting v =
match v with
| int -> (*expression1*)
| bool -> (*expression2*)
| _ -> (*expression3*)
也会产生表达式1。使用此代码
disting true
这个也有类似的问题。我怎样才能得到我想要的结果?
答案 0 :(得分:5)
模式匹配不像您认为的那样有效。
它允许您将表达式与值或值模式匹配,如下所示:
match some_int with
| 1 -> 1
| 10 -> 2
| x -> x/2 (* this matches any possible int, and it gives it the name 'x' for the rest *)
所以在这里你将始终匹配你的第一个案例,因为它不会过滤任何东西。你所说的是:将v与任何东西匹配,让其在其余部分称之为“bool”。
然后你可以试试像
这样的东西let disting v =
match v with
| true -> (*expression2*)
| 2 -> (*expression1*)
| _ -> (*expression3*)
在OCaml中没有进行类型检查,因为'v'既可以是int也可以是bool,但不能同时使用。 我不知道你要做什么,但你应该阅读一些关于语言的基础。
答案 1 :(得分:2)
在Ocaml中执行此操作的方法是使用和类型:
type i_or_b = I of int | B of bool;
let disting v =
match v with
| I x -> Printf.printf "v = I %d\n" x
| B x -> Printf.printf "v = B %s\n" (string_of_bool x)
答案 2 :(得分:0)
tl; dr:编写两个不同的函数,一个用于int,一个用于bool,并根据上下文调用适当的函数。
Pierre G.提供了一个很好的方法来实现你想要做的事情。虽然,我想补充一点,我相信你想要完成的是功能编程中的根本错误;检查运行类型的类型只是命令式编程的典型。原因如下:
一个函数是一个从空间中获取一些元素并从另一个空间输出一个元素的映射,这就是为什么我们在数学上写f: X -> Y
来表示函数是从空间X
到空间Y
。特别是f
只能将X
中的元素作为输入。如果X
是自然数字的空间,则调用f(dog)
是没有意义的。
我们所说的一切基本上都是函数式编程中发生的事情,只需用类型替换空间就可以得到函数是从一种类型到另一种类型的映射。这就是为什么我们使用诸如f :: int -> int
之类的符号作为我们的函数签名,然后就没有明确定义f true
意味着什么,因此你的程序将无法编译,因为它没有任何意义。
再次,你可以使用皮埃尔的解决方案并定义一个类型(空间),它实际上是int和bool的联合。
type intOrBool = Int of int | Bool of bool;
然后定义类型为intOrBool -> [output type]
的函数。但是再次理解它与可以同时接收int或bool的函数不同,因为intOrBool是一种全新的类型。
为什么以这种方式思考你的问题如此重要?因为函数式编程的强度正是如此:如果没有明确定义,它将无法编译。在命令式语言中,您有一些函数可以接收某些类型,例如int,但仍会接受任何类型。这可能会使他们崩溃,或者最糟糕的是会产生意外行为,从而导致混淆,咖啡滥用和security breaches。
从更实际的角度来看,这实际上是我们刚才解释的理论的结果,OCaml不会在运行时跟踪类型。类型检查都是在编译之前完成的,因为一旦我们知道一切都将被很好地定义,为什么我们要记住这些信息呢?从数学上讲,我们确信错误类型不会发生错误。
总之,我个人对你的问题的回答是你应该写两个不同的函数,一个是take和int,另一个是bool并实现你想要的行为。这具有可重用性的优点,对于大多数情况下你想要完成的事情都有好处,最后更接近你通常在函数式编程中使用的策略,即编写然后编写小型构建块函数。