我已经阅读了这个问题,但我对这个crossinline关键字有一个更基本的问题.我不确定它解决了什么问题以及如何解决它.
来自Kotlin Docs,
请注意,某些内联函数可能会将传递给它们的lambda作为参数调用,而不是直接来自函数体,而是来自另一个执行上下文,例如本地对象或嵌套函数.在这种情况下,lambda中也不允许非本地控制流.为了表明这一点,lambda参数需要用crossinline修饰符标记:
[强调补充]
这句话对我来说很模糊.首先,我在实际描绘"此类情况"的含义时遇到了麻烦.我对这个问题有一个大概的概念,但不能提出一个很好的例子.
其次,短语"表明这一点"可以多种方式阅读.说明什么?这一个特殊情况是不允许的?这是允许的吗?允许(或不允许)给定函数定义中的非本地控制流?
简而言之,我很难弄清楚使用它的上下文是什么,使用它与客户端通信的内容,以及应用此关键字的预期结果是什么.
我一直在研究FP语言(关闭和开启)一段时间,并且使用过Scala,Haskell,F#和其他一些语言.我喜欢我所看到的并理解FP的一些基本概念(绝对没有类别理论的背景 - 所以请不要谈数学,请).
所以,给定一个类型,M[A]我们有map一个函数,A=>B并返回一个M[B].但我们也有flatMap一个功能A=>M[B]并返回一个M[B].我们也有flatten一个M[M[A]]并且返回一个M[A].
此外,许多的来源我已阅读形容flatMap为map其次flatten.
所以,鉴于这flatMap似乎相当于flatten compose map,它的目的是什么?请不要说它是支持'for comprehensions',因为这个问题确实不是Scala特有的.我不太关心语法糖,而不是我背后的概念.Haskell的bind运算符(>>=)也出现了同样的问题.我相信它们都与某些类别理论概念有关,但我不会说那种语言.
我已经看过Brian Beckman的精彩视频Do not Fear the Monad不止一次,我想我看到那flatMap是monadic组合运算符,但我从未真正看到它使用了他描述这个运算符的方式.它执行此功能吗?如果是这样,我该如何将该概念映射到flatMap?
顺便说一句,我在这个问题上写了很长的文章,上面有很多列表显示我试图深入了解其中的实验flatMap,然后遇到了这个回答我的一些问题的问题.有时我讨厌Scala暗示.他们真的可以在水中浑浊.:)
我一直在努力了解State Monad.与其如何使用不同,尽管这并不总是很容易找到.但是我发现的State Monad的每一次讨论基本上都有相同的信息,总有一些我不理解的东西.
以这篇文章为例.其中作者有以下内容:
case class State[S, A](run: S => (A, S)) {
...
def flatMap[B](f: A => State[S, B]): State[S, B] =
State(s => {
val (a, t) = run(s)
f(a) run t
})
...
}
Run Code Online (Sandbox Code Playgroud)
我可以看到类型正确排列.但是,我根本不理解第二个run.
也许我正在错误地看待这个monad的整个目的.我从HaskellWiki得到的印象是,状态monad有点像run允许转换的状态机(但在这种情况下,状态机并不像大多数状态机那样具有固定的状态转换).如果是这种情况,那么在上面的代码(a, t)中将表示单个转换.应用程序f将表示该值的修改和State(生成新的State对象).这让我完全不知道第二个run是什么.这似乎是第二次"过渡".但这对我没有任何意义.
我可以看到,调用run生成的State对象会产生一(A, S)对新的对,当然,这些类型需要排列.但我真的不明白这应该是做什么的.
那么,这里到底发生了什么?在这里建模的概念是什么?
编辑:2015年12月22日
所以,看来我并没有很好地表达我的问题.让我试一试.
在同一篇博文中,我们看到以下代码map:
def map[B](f: A => B): State[S, B] =
State(s => {
val …Run Code Online (Sandbox Code Playgroud) 我只是查找了HasResolution 类型类,它有一个方法,resolution声明如下:
class HasResolution a where
...
resolution :: p a -> Integer
Run Code Online (Sandbox Code Playgroud)
我不明白p上面的声明.它来自哪里,它意味着什么?
我正在阅读"Scala中的函数编程"一书,并且遇到了一个我不完全理解的例子.
在关于严格/懒惰的章节中,作者描述了Streams的构造,并且代码如下:
sealed trait Stream[+A]
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream {
def cons[A](hd: => A, tl: => Stream[A]) : Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head, () => tail)
}
...
}
Run Code Online (Sandbox Code Playgroud)
我的问题是在smart constructor(cons)中,它调用Conscase类的构造函数.用于传递head和tailval 的特定语法对我来说没有意义.为什么不像这样调用构造函数:
Cons(head, tail)
Run Code Online (Sandbox Code Playgroud)
据我所知,它使用的语法是强制创建两个只返回head和tailval的Function0对象.这与仅仅传递head和tail …
我正在阅读一本书,内容如下:
sealed trait Currency
case object USD extends Currency
... other currency types
case class Money(m: Map[Currency, BigDecimal]) {
... methods defined
}
Run Code Online (Sandbox Code Playgroud)
讨论继续将 on 的某些类型的操作识别Money为 Monoidal,因此我们要创建一个Monoidfor Money。但是接下来是我无法正确解析的列表。
首先是 的定义zeroMoney。这是按如下方式完成的:
final val zeroMoney: Money = Money(Monoid[Map[Currency, BigDecimal]].zero)
Run Code Online (Sandbox Code Playgroud)
我在这里遇到的问题是Money参数列表中的部分。具体来说
Monoid[Map[Currency, BigDecimal]].zero
Run Code Online (Sandbox Code Playgroud)
这是应该构造什么吗?到目前为止,在讨论中还没有实现该zero功能,Monoid[Map[A,B]]这是什么意思?
以下是以下内容:
implicit def MoneyAdditionMonoid = new Monoid[Money] {
val m = implicitly(Monoid[Map[Currency, BigDecimal]])
def zero = zeroMoney
def op(m1: Money, m2: Money) = Money(m.op(m1.m, m2.m))
} …Run Code Online (Sandbox Code Playgroud) 如果查看pandoc文档,您会看到用Haskell编写的脚本.我最近才学习了Haskell的基础知识,所以我不熟悉这些脚本中似乎出现的一些习语.
我不明白的一件事是def在这些脚本中使用.例如,在Text.Pandoc的顶部是以下代码:
markdownToRST :: String -> String
markdownToRST =
(writeRST def {writerReferenceLinks = True}) . readMarkdown def
main = getContents >>= putStrLn . markdownToRST
Run Code Online (Sandbox Code Playgroud)
'def'在做什么之后做readMarkdown了writeRST什么?
在"了解你一个Haskell"一书中,第11章我们介绍了newtype关键字,这一切对我来说都是有意义的,我们看到将Pair类型作为Functor的一个实例.
本讨论以一个问题陈述开始,即"只有一个参数的类型构造函数可以成为Functor的一个实例".我不明白这个说法.这个限制在哪里描述过?
在讨论的上下文中,我们有一个类型对定义为:
newtype Pair b a = Pair { getPair :: (a,b) }
Run Code Online (Sandbox Code Playgroud)
鉴于此,我本以为我们可以使用类似的东西:
instance Functor (Pair a b) where ...
Run Code Online (Sandbox Code Playgroud)
我原以为(Pair ab)会在Functor的定义中替换'f'而没有任何问题.什么阻止这种工作?
接下来,作者继续使用以下方法使Pair成为Functor的实例:
instance Functor (Pair c) where ...
Run Code Online (Sandbox Code Playgroud)
这是我迷路的地方.我不记得曾经在类型构造函数中看到"部分应用"类型.我不确定在这种情况下这甚至意味着什么,更不用说它如何解决上面提到的问题.
我想我在某个地方有一种误解,但我不知道该去哪里寻找它.我确实找到了这个答案,但它似乎只是回答这个问题的一部分.
我正在阅读Typeclassopedia,但在应用程序部分遇到了麻烦。我想我(有点)已经弄清楚了,但我想看看我的理解是否正确。
直到组合法出现之前,适用法则才有意义。我只是无法解析其右侧:
u <*> (v <*> w) = pure (.) <*> u <*> v <*> w
Run Code Online (Sandbox Code Playgroud)
因此,我启动了 GHCI 并进行了一些实验。
Prelude> pure (.) <*> Just (+1) <*> Just (+2) <*> Just 34
Just 37
Run Code Online (Sandbox Code Playgroud)
所以这验证了规律,但我还是不明白。我尝试了一些变化,看看是否可以获得一些见解:
Prelude> pure (.) <*> Just (+1) <*> Just (+2) <*> Just (+3) <*> Just 34
<interactive>:26:1: error:
* Non type-variable argument in the constraint: Num (b -> b)
(Use FlexibleContexts to permit this)
* When checking the inferred type
it :: forall b. (Num …Run Code Online (Sandbox Code Playgroud) 我发现了几个sequence用于创建序列(不再调用stream)的新函数的引用. JetBrains博客提供了以下示例:
val elements = sequence(1, { x -> x + 1})
val elements = listOf(1, 2, 3, 4).sequence()
Run Code Online (Sandbox Code Playgroud)
AgileWombat博客提供了类似的例子.
val squares = sequence(1) {it + 1}.map {it * it}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试这些示例中的任何一个时,无论是在REPL中还是在IDE中(IDEA 2016.1),我都会得到以下结果:
>>> val squares = sequence(1) {it + 1}.map {it * it}
error: unresolved reference: sequence
val squares = sequence(1) {it + 1}.map {it * it}
^
error: unresolved reference: it
val squares = sequence(1) {it + 1}.map {it …Run Code Online (Sandbox Code Playgroud) 我的问题类似于如何使点轨道成为直线,3D,但那里的答案似乎并不能解决我的问题。我正在寻找的是一种通用的解决方案。
作为记录,我正在尝试解决OpenGL ES(Java / Android)中的问题。
我有一个以3D点为中心的圆,一个半径和一个3D矢量,指定该圆所处平面的法线。
我需要找到一个3D点,该点代表与“旋转的” X轴(根据法向矢量旋转)成给定角度的圆周上的点。
我已经在Circle成员函数的类中有一个实现,该实现在pointAt有限的情况下有效。具体来说,在我当前的实现中,我假定圆位于XY平面中并相应地返回一个点,然后,由于我知道圆实际上位于XZ平面中,因此我只需在返回的点中交换Y和Z值即可。但是,这不是一般的解决方案,而这正是我需要的。
当我尝试了如何使点轨道变成直线3D中给出的算法时,我得到的点与应有的位置相差很远。
那么,如何计算这样一个圆的圆周上的点呢?
[编辑]我想我的解释还不够。我的假设是,圆在XY平面中“正常”,在Z方向上的法向矢量为(0,0,1)-1。如果需要圆周上的一点,则该点定义为:
x = R*cos(a) + Cx
y = R*sin(a) + Cy
Run Code Online (Sandbox Code Playgroud)
其中R是半径,Cx和Cy是X与Y所述圆的中心的坐标,并且a是从一个矢量的角度通过所述圆的圆心点和与所述X轴平行。
现在,如果圆没有沿Z轴指向的法线向量,而是某个任意(x,y,z)向量,那么如何找到相同的点?
haskell ×4
scala ×4
kotlin ×2
3d ×1
android ×1
applicative ×1
flatmap ×1
geometry ×1
java ×1
monoids ×1
opengl-es ×1
pandoc ×1
pass-by-name ×1
state-monad ×1