Functional programming 寻找学习练习:实现这些单子

Functional programming 寻找学习练习:实现这些单子,functional-programming,monads,Functional Programming,Monads,在学习新的编程课程时,我通常遵循一种模式:我阅读、理解它,然后编写一些示例以确保我真正理解它 我读过很多关于单子的书,我相信我能理解并理解它们。我现在正处于这样一个阶段,我真的很想编写一些单子来巩固我的理解,并真正弄清楚如何为各种类型实现绑定 问题是我想不出有多少明显的单子可以实现,所以我在寻找建议。最好是,我想要一份建议清单,包括一些简单的建议和一些不太简单的建议 我还意识到,虽然单子被用来“封装”功能程序中的副作用,但它们也比这更通用。所以,我希望建议包括单子,它既包含副作用,也包含一些一般

在学习新的编程课程时,我通常遵循一种模式:我阅读、理解它,然后编写一些示例以确保我真正理解它

我读过很多关于单子的书,我相信我能理解并理解它们。我现在正处于这样一个阶段,我真的很想编写一些单子来巩固我的理解,并真正弄清楚如何为各种类型实现绑定

问题是我想不出有多少明显的单子可以实现,所以我在寻找建议。最好是,我想要一份建议清单,包括一些简单的建议和一些不太简单的建议

我还意识到,虽然单子被用来“封装”功能程序中的副作用,但它们也比这更通用。所以,我希望建议包括单子,它既包含副作用,也包含一些一般的副作用

谢谢


(附带说明:我将与f#合作完成这项工作,但我认为这个问题可以适用于任何函数式语言)

遵循某种一元法则的数据结构/计算列表非常丰富

它从可选数据(
'a option
在F#)上的列表、延续和多线程到高度复杂的东西,比如解析器

只要开始实现其中的一些。 基本练习:

// Identity monad

let something = ident {
    let! value = id 42
    return value
}

let somethingelse = ident {
    let! value = something
    let! otherValues = id 40
    return value + othervalue
}


// Implement maybe for 'a option
let sum = maybe {
    let! a = maybeInputNumber("a")
    let! b = maybeInputNumber("b")
    let! c = maybeInputNumber("c")
    return a + b + c
}

match sum with
| None -> ...
| Some(n) -> ...
您还可以通过使用一些辅助函数和显式一元语法来增加您的理解

// Given m >>= f for m.Bind(f)

let (>-) f monad = monad >>= (fun k -> return(f x))

// What's this?
let res = ((+) 1) >- [1..10]
如果您想要一些复杂的示例,请查看。这将允许您在纯F#中实现复杂的递归下降解析器(请看-Project)

这方面的一个简单实现基于以下类型:

type 't Computation = 
    | Error of ...
    | Result of 't

type Input     = char list
type 'a Parser = Input -> (('a * Input) Computation)
尝试实现绑定并返回;-)


作为一般提示:如果你真的想了解单子在自然环境中的情况,你必须使用Haskell;-)在F#中只有计算表达式,只是一个模糊的模拟,但Haskell为任何一元计算引入了通用接口。非常适合尝试

我认为中的目录是一个很好的开始(延续单子实际上对反同构很有用,参见示例);此外,而且可能。是另一个很好的尝试自己实现的代码(逻辑上是单线程代码,跨不同的实际线程跳变为非阻塞)。基本的单子看起来是一个很好的高级挑战。

虽然我认为Haskell是学习单子的自然语言这一事实没有什么挑战性,但我发现一个非常有用的练习是将单子计算引入一种语言,而这种语言不是现成的,为它们提供Haskell般的超级平滑支撑。这在任何语言中都是完全可能的,而且在任何合理的高级语言中,都有可能具有创造性并使它们看起来更漂亮——在这个过程中学习了很多!例如,我已经看到了Python很酷的一元语法(我想是at)

还有Clojure的Clojure.contrib.monads库,它为在Lisp中使用monads提供了很好的工具。试着从功能上重现它的一些特性可能会很有启发性。此外,有时使用它来代替Haskell可能有助于将一般模式与Haskell语法的细节分离开来(尽管它们确实很好)

type 't Computation = 
    | Error of ...
    | Result of 't

type Input     = char list
type 'a Parser = Input -> (('a * Input) Computation)