我已经尝试过阅读这个但我仍然不明白它们的价值或它们取代的东西.他们是否让我的代码更短,更容易理解?
很多人发布了答案,但很高兴看到有和没有换能器的例子非常简单,甚至像我这样的白痴也能理解.除非传感器当然需要一定程度的理解,在这种情况下我永远不会理解它们:(
有人可以告诉我有限状态传感器是什么吗?
我读过维基百科的文章并且不理解.
在阅读了介绍传感器的Clojure(http://blog.podsnap.com/ducers2.html)上的这篇文章之后,我对传感器的含义感到困惑.是否部分应用于map
Haskell,如map (+1)
传感器?起初我认为这是使用部分应用程序的Clojure方式,但随后本文继续在Haskell中使用显式类型实现它.它在Haskell中有什么用?
我一直想知道是否有一种方法可以用惯用的方式在Haskell中定义和使用有限状态传感器.
您可以将FST作为生成器(它生成类型为{x1,x2}的输出),或者作为识别器(给定类型为{x1,x2}的输入,如果它属于理性关系则识别它),或者作为转换器(给定输入磁带,它将其转换为输出磁带).表示会根据方法而改变吗?
是否也可以通过指定重写规则来生成FST模型?例如,创建一个DSL来模拟重写规则,然后创建一个函数createFST :: [Rule] -> FST
.
我能找到的最接近的是Kmett,Bjarnason和Cough的machines
图书馆:https:
//hackage.haskell.org/package/machines
但我似乎无法意识到如何用FST建模FST Machine
.我认为这样做的正确方法与他们定义Moore和Mealy机器的方式类似:将FST定义为不同的实体,但提供一个Automaton
能够将其用作机器的实例.
我也找到了其他一些选项,但是他们以一种简单的方式定义它(比如在https://hackage.haskell.org/package/fst中).这并不能说服我,因为我想知道是否有更好的方法来使用Haskell类型系统的优势(比如Moore和Mealy机器如何在machines
库中定义).
当我在Clojure中学习传感器时,它突然让我想起了他们提醒我的:Java 8流!
甲流是不是一个数据结构,用于存储内容; 相反,它通过计算操作管道传递来自诸如数据结构,数组,生成器函数或I/O通道的源的元素.
Clojure的:
(def xf
(comp
(filter odd?)
(map inc)
(take 5)))
(println
(transduce xf + (range 100))) ; => 30
(println
(into [] xf (range 100))) ; => [2 4 6 8 10]
Run Code Online (Sandbox Code Playgroud)
Java的:
// Purposely using Function and boxed primitive streams (instead of
// UnaryOperator<LongStream>) in order to keep it general.
Function<Stream<Long>, Stream<Long>> xf =
s -> s.filter(n -> n % 2L == 1L)
.map(n -> n + 1L)
.limit(5L);
System.out.println(
xf.apply(LongStream.range(0L, …
Run Code Online (Sandbox Code Playgroud) 在1.7版本的Clojure Core文档中 - 以下功能
dedupe
disj!
dissoc!
filter
keep
map
random-sample
remove
replace
take-while
Run Code Online (Sandbox Code Playgroud)
在其API描述中包含以下文本
Returns a transducer when no collection is provided.
Run Code Online (Sandbox Code Playgroud)
以及以下功能
drop
keep-indexed
partition-all
partition-by
take
take-nth
Run Code Online (Sandbox Code Playgroud)
有以下文字.
Returns a *stateful* transducer when no collection is provided.
Run Code Online (Sandbox Code Playgroud)
此外 - 对这一措辞提出了批评.
我的问题是:什么是有状态传感器?即分组函数的相似之处.(这是说,之所以有人说键入一个传感器就需要依赖类型?)
随着新的clojure 1.7我决定了解我可以使用传感器的位置.我明白他们能给予什么好处,但我找不到正常的编写自定义传感器的例子.
好的,我试着测试发生了什么.我打开了clojure文档.并且有一些例子xf
用作参数.第一:这个xf或xfrom是什么意思?这个东西产生了身份传感器
(defn my-identity [xf]
(fn
([]
(println "Arity 0.")
(xf))
([result]
(println "Arity 1: " result " = " (xf result))
(xf result))
([result input]
(println "Arity 2: " result input " = " (xf result input))
(xf result input))))
Run Code Online (Sandbox Code Playgroud)
我[result input]
从文档示例中获取了变量的命名.我认为它在减少功能的地方result
是减少部分并且input
是新的集合元素.
所以,当我(transduce my-identity + (range 5))
得到结果时10
,我期待的结果.然后我读到了eduction
,但我无法理解它是什么.无论如何,我做了(eduction my-identity (range 5))
并得到了:
Arity 2: nil 0 = nil
Arity 2: nil 1 = nil …
Run Code Online (Sandbox Code Playgroud) 在Scala中实现有限状态机(或有限状态传感器)的一般方法是什么?
我经常发现自己需要实现状态机.我的典型实现看起来像
object TypicalFSM { // actually — finite state transducer
type State
case object State1 extends State
case object State2 extends State
type Message
case object Message1 extends Message
type ResultMessage
case object ResultMessage1 extends ResultMessage
}
import TypicalFSM._
class TypicalFSM extends ((Message) =>Seq[ResultMessage]){
var state:State = State1
def apply(message:Message):Seq[ResultMessage] = (state, message) match {
case (State1, Message1) =>
state = State2
Seq(ResultMessage1, ResultMessage2)
}
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢的是可变性var
使得解决方案线程不安全.FSM拓扑也不清楚.
如何以功能方式创建FSM?
以.dot格式绘制FSM图也是非常好的
Akka FSM具有允许将一些数据与状态关联的良好属性,而不仅仅是提供对象名称.这也是值得赞赏的.(但是,Akka FSM并不总是方便使用,因为它是异步的,有时候有点重量级.)
让我们从定义开始:A transducer
是一个函数,它接受一个reducer
函数并返回一个reducer
函数.
A reducer
是一个二元函数,它接受累加器和值并返回累加器.一个reducer可以用一个reduce
函数执行(注意:所有函数都是curry但是我已经把它和它的定义pipe
以及compose
为了便于阅读 - 你可以在现场演示中看到它们):
const reduce = (reducer, init, data) => {
let result = init;
for (const item of data) {
result = reducer(result, item);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
随着reduce
我们可以实现map
和filter
功能:
const mapReducer = xf => (acc, item) => [...acc, xf(item)];
const map = (xf, arr) => reduce(mapReducer(xf), [], arr);
const filterReducer = predicate => (acc, item) => …
Run Code Online (Sandbox Code Playgroud) 有状态转换器预计会在调用“完整”元数(即[([result input] )
)之前根据需要多次调用“步骤”元数(即([result] )
)来刷新其状态。
我的问题是reduced
这里如何处理提前终止(使用 )。
在https://clojure.org/reference/transducers#_early_termination \nit 说
\n\n\n在完成步骤中,具有缩减状态的传感器应在调用嵌套的 Transformer\xe2\x80\x99s 完成函数之前刷新状态,除非它之前已经看到来自嵌套步骤的缩减值,在这种情况下,应丢弃挂起状态。
\n
但“以前见过”是什么意思?
\n对上述引用有三种可能的解释:\n如果嵌套转换器的“步骤”数量已返回一个reduced
值,则“完整”步骤应该
看看partition-by
它的实现,似乎第一个选项适用:
([result]\n (let [result (if (.isEmpty a)\n result\n (let [v (vec (.toArray a))]\n ;;clear first!\n (.clear a)\n (unreduced (rf result v))))]\n (rf result)))\n
Run Code Online (Sandbox Code Playgroud)\n在将此未减少的值传递给嵌套变换的“完整”数量之前,这还会从使用剩余状态调用嵌套变换的“步骤”数量的结果中删除“减少”。
\n那么问题是,如果我有一个有状态的减速器,在其完成步骤中会多次调用其嵌套转换的“步骤”数量,那么如果它在reduced
完成步骤中看到一个值,它应该如何反应?
尝试将上面的引用和代码结合起来,我认为它应该停止调用“step”arity并直接调用具有unreduced
类似值的“complete”arity partition-by
。
但是,然后查看代码cat …
transducer ×10
clojure ×6
haskell ×2
fsm ×1
java ×1
java-8 ×1
java-stream ×1
javascript ×1
scala ×1
stateful ×1
terminology ×1