标签: functional-programming

是否有scala身份功能?

如果我有类似的东西List[Option[A]],我想将其转换为a List[A],标准方法是使用flatMap:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)
Run Code Online (Sandbox Code Playgroud)

现在o => o只是一个身份功能.我原以为会有办法:

l.flatMap(Identity) //return a List[String]
Run Code Online (Sandbox Code Playgroud)

但是,我不能让这个工作,因为你不能生成一个object.我试了几件事无济于事; 有没有人有这样的工作?

functional-programming scala scala-option

65
推荐指数
2
解决办法
3万
查看次数

何时以及为什么要在Scala中使用Applicative Functors

我知道Monad可以在Scala中表达如下:

trait Monad[F[_]] {
  def flatMap[A, B](f: A => F[B]): F[A] => F[B]
}
Run Code Online (Sandbox Code Playgroud)

我明白为什么它有用.例如,给定两个功能:

getUserById(userId: Int): Option[User] = ...
getPhone(user: User): Option[Phone] = ...
Run Code Online (Sandbox Code Playgroud)

我可以轻松编写函数,getPhoneByUserId(userId: Int)因为它Option是一个monad:

def getPhoneByUserId(userId: Int): Option[Phone] = 
  getUserById(userId).flatMap(user => getPhone(user))
Run Code Online (Sandbox Code Playgroud)

...

现在我Applicative Functor在Scala中看到:

trait Applicative[F[_]] {
  def apply[A, B](f: F[A => B]): F[A] => F[B]
}
Run Code Online (Sandbox Code Playgroud)

我想知道何时应该使用它而不是 monad.我猜选项和列表都是Applicatives.你能给出使用applyOption和List的简单例子,并解释为什么我应该使用它而不是 flatMap

functional-programming scala applicative

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

Spark代码组织和最佳实践

因此,在面向对象的世界中花费了多年的代码重用,设计模式和最佳实践总是被考虑在内,我发现自己在Spark世界中的代码组织和代码重用方面有些挣扎.

如果我尝试以可重用的方式编写代码,它几乎总是带来性能成本,我最终会将其重写为适合我的特定用例的最佳代码.这个常量"为这个特定用例编写最佳内容"也会影响代码组织,因为当"它们真的属于一个整体"时,将代码拆分成不同的对象或模块是困难的,因此我最终只得到很少的"上帝"对象包含长复杂变换链.事实上,我经常认为,如果我在面向对象世界工作时看到我现在正在写的大部分Spark代码,我会畏缩并将其视为"意大利面条代码".

我上网试图找到某种等同于面向对象世界的最佳实践,但没有太多运气.我可以找到一些函数式编程的"最佳实践",但Spark只增加了一个额外的层,因为性能是这里的一个主要因素.

所以我的问题是,你们中的任何人都有Spark专家发现了一些你可以推荐的编写Spark代码的最佳实践吗?

编辑

正如评论中所写,我实际上并没有希望有人就如何解决这个问题发表答案,而是我希望这个社区中的某个人遇到一些Martin Fowler类型,他曾在某处写过som文章或博客帖子关于如何解决Spark世界中代码组织的问题.

@DanielDarabos建议我举一个代码组织和性能相互矛盾的例子.虽然我发现我在日常工作中经常遇到这方面的问题,但我觉得把它归结为一个很好的最小例子有点困难;)但我会尝试.

在面向对象的世界里,我是单一责任原则的忠实粉丝,所以我要确保我的方法只对一件事负责.它使它们可重复使用并且易于测试.因此,如果我不得不计算列表中某些数字的总和(匹配某些标准)并且我必须计算相同数字的平均值,我肯定会创建两个方法 - 一个计算总和,一个计算平均值.像这样:

def main(implicit args: Array[String]): Unit = {
  val list = List(("DK", 1.2), ("DK", 1.4), ("SE", 1.5))

  println("Summed weights for DK = " + summedWeights(list, "DK")
  println("Averaged weights for DK = " + averagedWeights(list, "DK")
}

def summedWeights(list: List, country: String): Double = {
  list.filter(_._1 == country).map(_._2).sum
}

def averagedWeights(list: List, country: String): Double = {
  val filteredByCountry = list.filter(_._1 == country) 
  filteredByCountry.map(_._2).sum/ filteredByCountry.length
}
Run Code Online (Sandbox Code Playgroud)

我当然可以继续尊重Spark中的SRP:

def main(implicit …
Run Code Online (Sandbox Code Playgroud)

functional-programming code-organization apache-spark

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

如何组成生锈功能?

我正在尝试编写一个组成两个函数的函数,初始设计非常简单,它是一个函数,它接受两个函数并返回一个组合函数,然后我可以用其他函数组合,(因为rust没有rest参数).但是我遇到了一个很长的硬墙,内置了令人沮丧的无用的编译器错误.

我的撰写功能:

fn compose<'a, A, B, C, G, F>(f: F, g: G) -> Box<Fn(A) -> C + 'a>
where
    F: 'a + Fn(A) -> B + Sized,
    G: 'a + Fn(B) -> C + Sized,
{
    Box::new(move |x| g(f(x)))
}
Run Code Online (Sandbox Code Playgroud)

我想怎么用它:

fn main() {
    let addAndMultiply = compose(|x| x * 2, |x| x + 2);
    let divideAndSubtract = compose(|x| x / 2, |x| x - 2);

    let finally = compose(*addAndMultiply, *divideAndSubtract);
    println!("Result is {}", finally(10));
}
Run Code Online (Sandbox Code Playgroud)

rustc不喜欢那样,无论我尝试什么,特质界限永远不会满足.错误是:

error[E0277]: the size …
Run Code Online (Sandbox Code Playgroud)

functional-programming rust

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

什么构成除列表以外的类型的折叠?

考虑一个单链表.它看起来像

data List x = Node x (List x) | End
Run Code Online (Sandbox Code Playgroud)

定义折叠函数是很自然的

reduce :: (x -> y -> y) -> y -> List x -> y
Run Code Online (Sandbox Code Playgroud)

从某种意义上说,reduce f x0替代每一个Nodef一位Endx0.这就是Prelude所说的折叠.

现在考虑一个简单的二叉树:

data Tree x = Leaf x | Branch (Tree x) (Tree x)
Run Code Online (Sandbox Code Playgroud)

定义诸如的函数同样很自然

reduce :: (y -> y -> y) -> (x -> y) -> Tree x -> y
Run Code Online (Sandbox Code Playgroud)

请注意,这种减少具有完全不同的特征; 而基于列表的一个本质上是顺序的,这个新的基于树的一个具有更多的分而治之的感觉.你甚至可以想象par在那里扔几个组合器.(你会在列表版本中放置这样的东西?)

我的问题:这个功能是否仍被归类为"折叠",还是其他东西?(如果是的话,它是什么?)

基本上每当有人谈论折叠时,他们总是谈论折叠列表 …

haskell functional-programming terminology fold

64
推荐指数
4
解决办法
8203
查看次数

Groovy集合的地图方法

mapGroovy中有方法吗?我想做一些像我使用以下Scala片段的事情:

scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)

scala> l.map(_ + 1)
res0: List[Int] = List(2, 3, 4)
Run Code Online (Sandbox Code Playgroud)

groovy functional-programming scala map

63
推荐指数
1
解决办法
3万
查看次数

python中的功能管道,如R's dplyr中的%>%

在R(感谢magritrr)中,您现在可以通过更多功能管道语法执行操作%>%.这意味着不是编码:

> as.Date("2014-01-01")
> as.character((sqrt(12)^2)
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

> "2014-01-01" %>% as.Date 
> 12 %>% sqrt %>% .^2 %>% as.character
Run Code Online (Sandbox Code Playgroud)

对我来说,这更具可读性,这扩展到数据框之外的用例.python语言是否支持类似的东西?

python functional-programming pipeline

63
推荐指数
12
解决办法
2万
查看次数

Java 8 Supplier在构造函数中包含参数

为什么供应商只支持no-arg构造函数?

如果存在默认构造函数,我可以这样做:

create(Foo::new)
Run Code Online (Sandbox Code Playgroud)

但如果唯一的构造函数采用String,我必须这样做:

create(() -> new Foo("hello"))
Run Code Online (Sandbox Code Playgroud)

java lambda functional-programming java-8 functional-interface

63
推荐指数
5
解决办法
7万
查看次数

C++中的函数式编程.实施f(a)(b)(c)

我已经开始使用C++进行函数式编程的基础知识.我正在尝试创建一个f(a)(b)(c)将返回的函数a + b + c.我成功实现了f(a)(b)返回a + b 的函数.这是它的代码:

std::function<double(double)> plus2(double a){
    return[a](double b){return a + b; };
}
Run Code Online (Sandbox Code Playgroud)

我只是无法弄清楚如何实现f(a)(b)(c)我之前声明应该返回的功能a + b + c.

c++ functional-programming currying c++11 std-function

63
推荐指数
7
解决办法
9115
查看次数

Scala Functor和Monad的差异

有人可以解释一下Scala上下文中Functor和Monad之间的区别吗?

functional-programming scala

62
推荐指数
4
解决办法
1万
查看次数