有个主意:函数(在FP中)可以像OOP中的组件一样组成.对于OOP中的组件,我们使用接口.对于函数,我们可以使用委托.目标是实现分解,模块化和可互换性.我们可以使用依赖注入来简化它.
我试着找一些关于这个话题的东西.没运气.可能是因为没有足够大的功能程序需要这个?在搜索用FP编写的企业级应用程序时,我找到了这个列表. 现实世界中的功能编程和本文.我希望我错过了FP的杀手级应用程序,这个应用程序足够大,值得分解.
问题:您能否展示出体现真实的FP应用程序(最好是开源),它将分解用于模块?
Bonus chatter:使用的常用模式是什么?什么样的功能通常会分解成单独的模块?这些实现是否曾被用于测试目的?
代码合同很有效,直到您必须为Contract.Assume(...)框架代码中的结果添加一个bazillion .例如,MemoryStream.ToArray()永远不会返回一个空数组,就像我在Reflector中查看它一样,但它没有记录为契约,所以我必须Assume到处都是.
是否有一种神奇的方法来为已经存在的功能创建合同库?我猜测,一旦你完成了几十个最常用的框架功能,这些警告就会变得更加可口.
暂且不管我们是否应该使用度量单位来表示像角度这样的无单位概念,假设我在F#中定义了单位degree和radian单位
type [<Measure>] degree =
static member ToRadians (d:float<degree>) : float<radian> = d * (Math.PI * 1.<radian>) / 180.0<degree>
and [<Measure>] radian =
static member ToDegrees (r:float<radian>) : float<degree> = r * 180.0<degree> / (Math.PI * 1.<radian>)
Run Code Online (Sandbox Code Playgroud)
我可以比较容易地使用它们
4.0<degree> |> degree.ToRadians
Run Code Online (Sandbox Code Playgroud)
看起来扩展成员会更加方便.所以我可以说
let d = 4.0<degree>
let r = d.ToRadians()
Run Code Online (Sandbox Code Playgroud)
但我无法以明显的方式定义扩展成员
type float<degree> with
member degrees.ToRadians() = degree.ToRadians(degrees)
Run Code Online (Sandbox Code Playgroud)
...这让我有以下错误
error FS0010: Unexpected identifier in type name. Expected infix operator, quote symbol or other token.
Run Code Online (Sandbox Code Playgroud)
对于F#中的度量单位,是否存在扩展成员的语法技巧,或者是否支持该功能?
我试图在F#中使用显式成员约束.文档说"F#支持公共语言运行库支持的完整约束集",但是如果我实际上编译了一个具有这种显式约束的类,比如下面的那样,我就会遇到异乎寻常的错误.
type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)> =
member this.F a b = a + b
Run Code Online (Sandbox Code Playgroud)
报告
错误FS0670:此代码不够通用.当^ T :(静态成员(+):^ T*^ T - > ^ T)时,类型变量^ T无法推广,因为它会逃避其范围.
并在定义网站上报告member this.F.这是什么意思?相关范围是什么?
这种语言支持许多方法来完成这类工作.可以在StackOverflow上找到一个很好的探索,但是我没有看到为什么不允许这种特殊的通用约束"逃避"的明确解释.
根据http://blogs.msdn.com/b/pfxteam/archive/2012/04/12/async-await-faq.aspx,await关键字在unsafe块内被禁止,仅提及"保留非托管指针所固有的困难". " 关于这些困难是什么有一个很好的解释?
这是一个我已经有一段时间的问题,但实际上从来没有问过......
在Visual Studio生成的很多设计器文件中,有些变量以global为前缀::有人可以解释这意味着什么,这个前缀做了什么以及我应该在哪里使用它?
虽然我问过,但Visual Studio 2010似乎没有为我的F#模块生成代码覆盖率统计信息.单元测试是用C#编写的Ms Tests,因此由Visual Studio本机运行,并且干净地执行.但似乎没有为正在测试的F#库创建任何覆盖信息.涉及的C#库分析得很好.
我错过了什么吗?
我已经添加了CollectionResolver作为我的Windsor内核的子解析器,它将正确地在已解析的对象上注入依赖项集合.也就是说,如果我有
class X { public X(IComponent[] components) { ... } }
container.Register(/* lots of IComponents */);
container.Register(Component.For<X>());
Run Code Online (Sandbox Code Playgroud)
components当我解决它时,构造函数的参数是正确构造的
container.Resolve<X>()
Run Code Online (Sandbox Code Playgroud)
但如果相反我只是想获得组件列表本身,
container.Resolve<IComponent[]>()
Run Code Online (Sandbox Code Playgroud)
我得到一个ComponentNotFound例外,抱怨我没有注册任何组件IComponent[].我发现这种不对称违反直觉因为我不确定为什么内核在解析它在构造函数/属性上发现的依赖关系时应该采取不同的行为,而不是它解析用户希望它解析的依赖关系.
在我们的应用程序的核心,我们使用Castle Windsor来管理我们的依赖项.我们将从第三方加载插件,这些插件可能正在使用他们自己的IoC容器.我们希望他们能够从核心接收依赖关系,例如通过构造函数注入核心的服务,但也从他们自己的IoC容器接收依赖关系.
看起来如果他们提供了服务提供者接口,Windsor可以使用它来解决未知的依赖关系,忽略结果(因为这些组件的生命周期是其他人的业务)并继续卡车运输.
但我也相信,当你尝试这样的事情时会出现一些很大的微妙之处.
我将创建一个可观察的(通过各种方式)并将其返回给感兴趣的各方,但是当他们完成倾听时,我想拆除可观察的,以便它不会继续消耗资源.另一种将其视为在pub子系统中创建主题的方法.当没有人再订阅某个主题时,您不希望再持有该主题及其过滤.