本文介绍了如何在F#中创建应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定以下类型和成员函数

  type Result<'TSuccess,'TError> = 
| 'TSuccess
|的成功错误'TError列表

成员this.apply fn =
匹配(fn,this)与
|成功(f),成功(x) - >成功(f x)
|错误(e),成功(_) - >错误(e)
|成功(_),错误(e) - >错误(e)
|错误(e1),错误(e2) - >错误(List.concat [e1; e2])

和以下内联函数

$ b'b

  let inline(*)(f:^ A)(t:^ A)= 
let apply'=( ^ A:(会员申请:^ A - > ^ A)(t,f))
apply'

此调用网站

  let y()=成功(fun x  - > x + 1) < * GT; (成功3)

我收到以下错误:

  let y()=成功(有趣的x  - > x + 1)*< (成功3);; 
----------- ^^^^^^^^^^^^^^^^^^^^^^^^
/ Users / robkuz / stdin( 473,12):错误FS0001:类型约束不匹配。
类型
结果<'a,'c>
与类型
不兼容结果<('a - >'b),'c>
当统一''a'和''a - >时,结果类型是无限的。 'b'

这是一个模拟Haskells Applicative的尝试,签名应该是

 (< *>):: forall fa b。应用f => f(a  - > b) - > f a  - > fb 

但是我没有afaik,没有办法在F#中表达这一点。



关于如何做到这一点的任何想法?

解决方案

一般来说,我认为它不是尝试在F#中模拟Haskell模式的一个好主意。在Haskell中,很多代码被写成非常通用的,因为monads和applicatives的使用更频繁。



在F#中,我更喜欢编写更专用的代码,因为您不需要编写monad或applicatives上的多态代码,这样可以更容易地看到发生了什么。所以,我不认为我会永远不想写在F#中练习任何应用的<> 运算符。



也就是说,你的代码的问题是<> 运算符使用相同的 ^ A 类型参数为参数和结果(虽然他们是在调用中的不同类型) - 如果您使用三个单独的类型参数它工作正常:



<$ (< *>)(f:^ B)(t:^ A):^ C =
let apply'=(^ A:(member apply :^ B - > ^ C)(t,f))
apply'


Given the following type and member function

type Result<'TSuccess, 'TError> =
    | Success of 'TSuccess
    | Error of 'TError list
    with
    member this.apply fn =
        match (fn, this) with
        | Success(f), Success(x) -> Success(f x)
        | Error(e), Success(_) -> Error(e)
        | Success(_), Error(e) -> Error(e)
        | Error(e1), Error(e2) -> Error(List.concat [e1;e2])

and the following inline function

let inline (<*>) (f: ^A) (t:^A) =
    let apply' = (^A : (member apply : ^A -> ^A) (t, f))
    apply'

And this call site

let y () = Success (fun x -> x + 1) <*> (Success 3)

I get the following error

 let y () = Success (fun x -> x + 1) <*> (Success 3);;
 -----------^^^^^^^^^^^^^^^^^^^^^^^^
 /Users/robkuz/stdin(473,12): error FS0001: Type constraint mismatch.
The type
   Result<'a,'c>
is not compatible with type
   Result<('a -> 'b),'c>
The resulting type would be infinite when unifying ''a' and ''a -> 'b'

This whole thing is an attempt to emulate Haskells Applicative and the signature should be

(<*>) :: forall f a b. Apply f => f (a -> b) -> f a -> f b

But I dont afaik there is no way to express that in F#

Any ideas on how to make that happen?

解决方案

In general, I think it is not a good idea to try to emulate Haskell patterns in F#. In Haskell, lot of code is written as very generic, because monads and applicatives are used more frequently.

In F#, I prefer writing more specialized code, because you do not need to write code polymorphic over monads or applicatives and it just makes it easier to see what is going on. So, I do not think I would ever want to write <*> operator that works over any "applicative" in practice in F#.

That said, the issue with your code is that the <*> operator uses the same ^A type parameter for both arguments and the result (while they are different types in the call) - if you use three separate type parameters it works fine:

let inline (<*>) (f: ^B) (t:^A) : ^C =
    let apply' = (^A : (member apply : ^B -> ^C) (t, f))
    apply'

这篇关于如何在F#中创建应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-02 05:48