在没有使用lambda函数或定义另一个"本地"函数的情况下,Haskell中是否有一种方法可以绑定第二个参数而不是第一个函数?
例.我有一个像二进制函数:
sub :: Int -> Int -> Int
sub x y = x - y
Run Code Online (Sandbox Code Playgroud)
现在,如果我想绑定第一个参数,我可以轻松地使用(sub someExpression):
mapSubFrom5 x = map (sub 5) x
*Main> mapSubFrom5 [1,2,3,4,5]
[4,3,2,1,0]
Run Code Online (Sandbox Code Playgroud)
如果我想绑定前n个参数而没有"gap",那就行得很好.
如果我想绑定第二个参数而不是第一个参数,我知道的两个选项更详细:
通过另一个本地功能:
mapSub5 x = map sub5 x
where sub5 x = sub x 5
*Main> mapSub5 [1,2,3,4,5]
[-4,-3,-2,-1,0]
Run Code Online (Sandbox Code Playgroud)
或者使用lambda:
mapSub5 x = map (\x -> sub x 5) x
Run Code Online (Sandbox Code Playgroud)
虽然两者都工作正常,但我喜欢"sub 5"的优雅,并想知道是否有一种类似的优雅方式来绑定函数的第n(n> 1)个参数?
在Haskell或F#等函数式语言中使用非详尽的模式机制通常被认为是一种不好的做法,这意味着指定的案例并未涵盖所有可能的输入案例?
特别是,我应该允许代码失败MatchFailureException等,还是应该总是覆盖所有情况并在必要时明确抛出错误?
例:
let head (x::xs) = x
Run Code Online (Sandbox Code Playgroud)
要么
let head list =
match list with
| x::xs -> x
| _ -> failwith "Applying head to an empty list"
Run Code Online (Sandbox Code Playgroud)
F#(与Haskell不同)给出了第一个代码的警告,因为[]-case没有被覆盖,但为了简洁起见,我可以忽略它而不破坏功能样式约定吗?MatchFailure确实很好地说明了问题......
只是为了澄清,当我说多个分配,并行分配,解构绑定我的意思是以下模式匹配宝石
scala> val (x,y) = Tuple2("one",1)
x: java.lang.String = one
y: Int = 1
Run Code Online (Sandbox Code Playgroud)
其分配"one"到x和1到y.
我试图做
val (x,y) = "a b".split()
Run Code Online (Sandbox Code Playgroud)
我期望scala会尝试将模式与模式进行模式匹配,如果数组的长度与模式的长度不匹配,则会抛出运行时异常.
我所有试图轻松转换Array为a的尝试Tuple2都是徒劳的.
scala> Tuple2(Array(1,2):_*)
<console>:7: error: wrong number of arguments for method apply: (T1,T2)(T1, T2)
in object Tuple2
Tuple2(Array(1,2):_*)
^
scala> Tuple2(Array(1,2).toList:_*)
<console>:7: error: wrong number of arguments for method apply: (T1,T2)(T1, T2)
in object Tuple2
Tuple2(Array(1,2).toList:_*)
Run Code Online (Sandbox Code Playgroud)
有没有任何巧妙的方法来使用数组或列表的多个赋值?
arrays functional-programming scala pattern-matching variable-assignment
(如何)以通用方式表示Scala中的monad(如MonadHaskell中的类型类)?是否有可能trait Monad为此目的定义一个?
我只是想知道是否可以使用函数式编程语言(Haskell/F#/ Caml)的模式匹配工具多次匹配相同的值.
试想下面的例子:
plus a a = 2 * a
plus a b = a + b
Run Code Online (Sandbox Code Playgroud)
当使用两个相似的值(将存储在其中a)调用函数时,将调用第一个变体.
一个更有用的应用程序就是这个(简化AST).
simplify (Add a a) = Mult 2 a
Run Code Online (Sandbox Code Playgroud)
但是Haskell拒绝这些代码并警告我有相互矛盾的定义a - 我必须做明确的case/if-checks而不是找出函数是否具有相同的值.是否有任何技巧可以表明我想要匹配的变量会多次出现?
f# haskell functional-programming pattern-matching guard-clause
我只是想知道(在一些严重的偏执和某些情况下)使用QuickSort算法是否会被视为应用程序中的安全风险.
它的基本实现和改进版本(如3-median-quicksort)都具有特定输入数据行为异常的特性,这意味着它们的运行时间在这些情况下可能会极大地增加(具有O(n^2)复杂性),更不用说堆栈溢出的可能性.
因此,我认为通过向程序提供预先排序的数据可能会造成伤害,导致算法表现得像这样,这可能会对例如多客户端Web应用程序产生不可预测的后果.
这个奇怪的案例是否值得任何安全考虑(因此会迫使我们使用Intro-或Mergesort)?
编辑:我知道有很多方法可以阻止Quicksort的最坏情况,但是语言集成排序(如.NET的3中位数)呢.他们会成为禁忌吗?
类型类似乎很有可能以非常一致,高效和可扩展的方式编写泛型和可重用函数.但仍然没有 "主流语言"提供它们 - 相反:概念,这是一个非常类比的想法,已被排除在下一个C++之外!
反对类型类的原因是什么?显然,许多语言正在寻找一种方法来处理类似的问题:.NET引入了通用约束和类似于IComparable允许函数的接口
T Max<T>(T a, T b) where T : IComparable<T> { // }
Run Code Online (Sandbox Code Playgroud)
对所有实现接口的类型进行操作.
Scala使用traits和所谓的隐式参数/视图边界的组合,它们会自动传递给泛型函数.
但是这里显示的两个概念都有很大的缺点 - 接口是基于继承的,因此由于间接而相对较慢,而且不可能让现有类型实现它们.
如果我们需要一个Monoid的抽象,我们可以很好地编写一个接口并让我们的类型实现它,但内置类型int可能永远不会在你的函数本机上运行.
相反,隐式参数与常规接口/特征不一致.
使用类型类,不会有问题(伪代码)
typeclass Monoid of A where
static operator (+) (x : A, y : A) : A
static val Zero : A
end
instance Int of Monoid where
static operator (+) (x : Int, y : Int) : Int = …Run Code Online (Sandbox Code Playgroud) 当它说明这一点时,似乎我必须同意这篇文章
[...]动态类型语言中的代码遵循静态类型约定
我遇到的很多动态语言代码确实看起来非常静态(思考PHP),而动态方法看起来有些笨拙或不必要.
大多数情况下,它只是省略类型签名,在类型推断/结构类型的上下文中,甚至根本不必暗示动态类型.
所以我的问题(并不意味着过于主观)是动态语言或应用领域都是这些更高级的动态语言特性(不能在静态/编译语言中轻松复制)实际上和在语言上使用.
例子:
这些技术的有用应用是什么?
我已经做了很长一段时间的Java并且大约6个月前开始使用Scala.我喜欢这门语言.我发现的一件事是有多种方法可以做.我不知道这是因为语言的性质还是因为它还很年轻而且不断发展,习惯用法和最佳实践还没有出现.
让我感到惊讶的是,我一直是perl人的蟒蛇,其中:
"应该有一个 - 最好只有一个 - 明显的做法."
对我来说比对我更有意义
"有不止一种方法可以做到这一点".
我很想知道你认为Scala适合这种规模的原因以及为什么?