在功能光学中,一个表现良好的棱镜(在scala中称为部分透镜,我相信)应该具有类型的集函数'subpart -> 'parent -> 'parent
,其中如果棱镜"成功"并且在结构上与'parent
给定的参数兼容,则它返回'parent
给定适当的子部分,修改为'subpart
给定值.如果棱镜"失败"并且在结构上与'parent
参数不相容,那么它将返回'parent
给定的未修改.
我想知道为什么棱镜不返回'parent option
(Maybe
对于Haskellers)来表示set函数的通过/失败性质?程序员是否应该能够从返回类型中判断该集合是否"成功"?
我知道在功能光学领域已经进行了大量的研究和思考,所以我肯定必须有一个我似乎无法找到的确定答案.
(我来自F#背景,所以如果我使用的语法对Haskell或Scala程序员来说有点不透明,我很抱歉).
我看到很多资源强烈鼓励程序员不要使用Debug.Trace
生产代码,因为缺乏参考透明度.我仍然不完全理解这个问题,似乎无法找到根本原因.
我的理解是跟踪不能改变任何表达式的输出(虽然它可以在某些情况下导致表达式以不同的顺序执行,或者导致表达式被评估,否则将被懒惰地跳过).因此,跟踪不会影响纯函数的输出.它不会抛出任何错误.那为什么它如此强烈地反对呢?(如果我上面的任何假设都不正确,请指出!).它只是一个哲学辩论,还是一个表演的事情,还是它能以某种方式实际引入一个错误?
当使用其他不太严格的语言进行编程时,我经常发现有兴趣的生产应用程序日志值有助于诊断我无法在本地重现的问题.
对于无法使用静态类型系统表达某些功能的情况,我正在尝试探索 F# 的动态功能。因此,我正在尝试mapN
为(比如说)Option
类型创建一个函数,但是我在创建一个具有动态参数数量的函数时遇到了麻烦。我试过了:
let mapN<'output> (f : obj) args =
let rec mapN' (state:obj) (args' : (obj option) list) =
match args' with
| Some x :: xs -> mapN' ((state :?> obj -> obj) x) xs
| None _ :: _ -> None
| [] -> state :?> 'output option
mapN' f args
let toObjOption (x : #obj option) =
Option.map (fun x -> x :> obj) x
let a = Some 5
let b …
Run Code Online (Sandbox Code Playgroud)