关于Scala中的yield命令和以下示例:
val values = Set(1, 2, 3)
val results = for {v <- values} yield (v * 2)
Run Code Online (Sandbox Code Playgroud)
PS.我知道这个例子没有遵循推荐的功能方式(也就是使用map),但它只是一个例子.
我有一个模型,它有一些Option字段,其中包含另一个Option字段.例如:
case class First(second: Option[Second], name: Option[String])
case class Second(third: Option[Third], title: Option[String])
case class Third(numberOfSmth: Option[Int])
Run Code Online (Sandbox Code Playgroud)
我从外部JSON收到这些数据,有时这些数据可能包含null,这就是这种模型设计的原因.
所以问题是:获得最深领域的最佳方法是什么?
First.get.second.get.third.get.numberOfSmth.get
Run Code Online (Sandbox Code Playgroud)
上面的方法看起来很丑陋,如果其中一个对象是None,可能会导致异常.我正在寻找Scalaz lib,但没有找到更好的方法来做到这一点.
有任何想法吗?提前致谢.
我试图将此Scala函数转换为返回惰性流,而不是急切地检索所有结果,并在所有结果都存在时将它们从Seq转换为Stream.我感觉问题在于(for(i < - 1到9; z < - solve(xs.updated(pos,i),pos))yield z)toStream.
任何建议表示赞赏.我正在寻找的另一个解决方案是在找到结果时返回结果.使用此解决方案,我可能只返回了1个结果.谢谢
isConflictAt(xs.updated(pos, 0), pos, xs(pos) 是约束检查功能.
def solve(xs : List[Int], pos: Int): Stream[List[Int]] = {
if (!isConflictAt(xs.updated(pos, 0), pos, xs(pos))) {
val pos = xs.indexOf(0)
if (pos < 0) {println(xs); Stream(xs) } else (for (i <- 1 to 9; z <- solve(xs.updated(pos, i), pos)) yield z) toStream
} else Stream.empty
}
Run Code Online (Sandbox Code Playgroud) 使用Scala 2.8.1,编译:
val t = (40, 2)
println(for ((i, j) <- List(t)) yield i + j)
val e: Either[String, (Int, Int)] = Right(t)
println(e.right.map {
case (i, j) => i + j
})
println(for ((i, j) <- e.right) yield i + j)
Run Code Online (Sandbox Code Playgroud)
给出这个:
test.scala:9: error: constructor cannot be instantiated to expected type;
found : (T1, T2)
required: Either[Nothing,(Int, Int)]
println(for ((i, j) <- e.right) yield i + j)
Run Code Online (Sandbox Code Playgroud)
根据Scala中的Programming,for表达式应该等同于map/case表达式,但只有后者才能编译.我做错了什么,我应该怎么做?
在光滑的(1.0),是做什么的区别.where(),.filter()并.withFilter()在表?
在API中,它们具有相似的签名,但不清楚它们是如何不同的:
def filter[T] (f: (E) ? T)(implicit wt: CanBeQueryCondition[T]): Query[E, U]
def where[T <: Column[_]](f: (E) ? T)(implicit arg0: CanBeQueryCondition[T]): Query[E, U]
def withFilter[T] (f: (E) ? T)(implicit arg0: CanBeQueryCondition[T]): Query[E, U]
Run Code Online (Sandbox Code Playgroud) F#Computation Expressions允许隐藏厚层语法糖背后的一元语法的复杂性.Scala中是否有类似的东西?
我认为这是为了理解......
例:
val f = for {
a <- Future(10 / 2) // 10 / 2 = 5
b <- Future(a + 1) // 5 + 1 = 6
c <- Future(a - 1) // 5 - 1 = 4
} yield b * c // 6 * 4 = 24
val result = f.get
Run Code Online (Sandbox Code Playgroud)
但它确实感觉不对.有更好的语法吗?
例如,你可以拥有哈斯克尔
main = do fromHandle <- getAndOpenFile "Copy from: " ReadMode
toHandle <- getAndOpenFile "Copy to: " WriteMode
contents <- hGetContents fromHandle … 我有一些代码片段,我生成多个列表(通过for comprehensions),然后连接它们.有一些单元素列表,但这不起作用.在Haskell中,我会做类似的事情
[42 | i == j]
Run Code Online (Sandbox Code Playgroud)
等价的是
(do guard (i == j)
return 42) :: [Int]
Run Code Online (Sandbox Code Playgroud)
要么
(guard (i == j) >>= \_ -> return 1) :: [Int]
Run Code Online (Sandbox Code Playgroud)
在斯卡拉我试过
for (if i == j) yield 42
Run Code Online (Sandbox Code Playgroud)
但它说"非法启动简单模式".
在回答Scala的收益时,作者说"Scala"对于理解"等同于Haskell的"do"符号.
此外,在Scala网站上,它说"理解具有(枚举)产生e的形式,其中枚举是指以分号分隔的枚举器列表.枚举器是引入新变量的生成器,或者是过滤器".但很明显,事实并非如此,因为过滤器似乎只能在发电机之后才能使用.
目前我使用
if (i == j) List(42) else Nil
Run Code Online (Sandbox Code Playgroud)
对于这种特殊情况,我可能不会更喜欢for comprehension语法,而只是使用if-then-else代替.在Haskell中,由于与数学集合构造符号的相似性,它看起来相当不错.
我的问题不是关于风格,而是更多关于技术细节:为什么Haskell和Scala之间的这种特殊情况存在差异?为什么不for (if i == j) yield 42工作?
我刚刚开始使用scala,我正在将一些java代码转换为scala,并尝试使其更好,功能更优雅.
我有以下代码包含一个方法(getRequiredUploadPathKeys),它提供了MyClass中所有可用路径模板所需的所有路径键的并集.
trait PathTemplate {
def getRequiredPathKeys:Set[PathKey]
}
class MyClass(accessPaths:Set[PathTemplate], targetPath:PathTemplate){
def getAllRequiredPathKeys: Set[PathKey] = {
val pathKeys = HashSet[PathKey]()
pathKeys.addAll(targetPath.getRequiredPathKeys)
for (accessTemp <- accessPaths) {
pathKeys.addAll(accessTemp.getRequiredPathKeys)
}
return pathKeys
}
}
Run Code Online (Sandbox Code Playgroud)
这个方法似乎在scala中可以更加简洁.任何人都可以指出我如何到达那里?
谢谢,保罗
无法弄清楚是否可以使用Scalaz 7编写类似的内容.我试图用代码块中的注释表达自己.
def validate1(p: String) = ValidationNel[String, Value] = ...
def validate2(p: String) = ValidationNel[String, Value] = ...
validateCombination(p1: String, p2: String) = {
// I would like to write something like
(validate1(p1) |@| validate2(p2)) { (v1, v1) =>
// And validate the combinations here and return successNel of failNel
}
}
def validate(p1: String, p2: String, p3: String) = {
(validateCombination(p1, p2) |@| validate1(p3)) { (v1, v2, v3) =>
// Notice the three parameters I want to have here …Run Code Online (Sandbox Code Playgroud) 编辑:我发现这是什么是斯卡拉的收益?(特别是第二个,最受欢迎的答案)在接受的答案解决了我的问题后非常有启发性.
==
我有一个HashMap,我想迭代它,并为每个键,使用for循环来创建新对象.
我正在尝试获取这些新对象的列表,但我总是给出一个空的"单元"序列.我想更好地理解我的代码的行为.
case class MyObject(one: String, two: String, three: Int)
val hm = new HashMap[String,Int]
hm += ("key" -> 3)
hm += ("key2" -> 4)
val newList = hm.map { case (key,value) =>
for (i <- 0 until value) {
new MyObject(key, "a string", i)
}}.toSeq
Run Code Online (Sandbox Code Playgroud)
结果:
newList:Seq[Unit] = ArrayBuffer((), ())
Run Code Online (Sandbox Code Playgroud)
如果我不在.map()中使用任何for循环,我有我期望的结构类型:
val newList = hm.map { case (key,value) =>
new MyObject(key, "a string", value)}.toSeq
Run Code Online (Sandbox Code Playgroud)
结果是:
newList:Seq[MyObject] = ArrayBuffer(MyObject(key,host,3), MyObject(key2,host,4))
Run Code Online (Sandbox Code Playgroud) 以下for-expression对我来说似乎很直观.取出每个项目List(1),然后映射List("a"),然后返回一个List[(Int, String)].
scala> val x = for {
| a <- List(1)
| b <- List("a")
| } yield (a,b)
x: List[(Int, String)] = List((1,a))
Run Code Online (Sandbox Code Playgroud)
现在,将它转换为a flatMap,对我来说似乎不太清楚.如果我理解正确,我需要先调用,flatMap因为我正在采取初始List(1),然后应用转换函数A => List[B].
scala> List(1).flatMap(a => List("a").map(b => (a,b) ))
res0: List[(Int, String)] = List((1,a))
Run Code Online (Sandbox Code Playgroud)
在使用flatMap之后,似乎有必要使用,map因为我需要从A => B.
但是,随着项目数量的增加for-expression(例如2到3项),我如何知道是否使用map或flatMap转换for-expression为flatMap?
我有两个清单:
val list1 = List("asdf", "fdas", "afswd", "dsf", "twea", "rewgds", "werwe", "dsadfs");
val list2 = List();
Run Code Online (Sandbox Code Playgroud)
我想过滤list1和setup2中的所有项目,以便它只包含不包含字母'a'的项目.我知道如何使用命令式编程来完成这项工作,但是如何通过功能编程实现这一目标?
在我的项目中,我们正在从 Java 迁移到 Scala。我必须使用 Java 中的一个函数,该函数在continuefor 循环中使用,并根据 for 循环内的 if 条件返回一个值,如下所示。
private TSourceToken getBeforeToken(TSourceToken token) {
TSourceTokenList tokens = token.container;
int index = token.posinlist;
for ( int i = index - 1; i >= 0; i-- ) {
TSourceToken currentToken = tokens.get( i );
if ( currentToken.toString( ).trim( ).length( ) == 0 ) {
continue;
}
else {
return currentToken;
}
}
return token;
}
Run Code Online (Sandbox Code Playgroud)
为了将其转换为 Scala,我使用了 Yield 选项来过滤掉满足 if 表达式的 else 条件的值,如下所示。
def getBeforeToken(token: TSourceToken): TSourceToken = …Run Code Online (Sandbox Code Playgroud) scala ×13
monads ×2
scalaz ×2
collections ×1
do-notation ×1
f# ×1
haskell ×1
java ×1
option ×1
scalaz7 ×1
slick ×1
stream ×1
validation ×1
yield ×1