You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持类型校验的F#函数组合器?对比C#实现差异

需求:实现类型匹配的F#函数组合器

需要编写一个Composer类的Compose方法,能够校验传入的两个函数类型:当第一个函数的输出类型与第二个函数的输入类型匹配时,返回组合后的函数(Some(f >> g));否则返回None。

示例代码

let f (i : int) : string = i.ToString()
let g (s : string) : char[] = s.ToCharArray()

// 期望返回 Some (f >> g)
let foo = Composer().Compose(f,g)
// 期望返回 None
let bar = Composer().Compose(g,f)

尝试的两种失败实现

1. 强制转换的暴力实现(运行时不允许)

这种实现试图通过类型判断后强制转换函数,但F#不允许此类运行时强制转换,无法工作:

type Composer() = 
    member _.Compose<'a,'b,'c,'d> (f : 'a -> 'b,g : 'c -> 'd) : ('a -> 'd) option =
        match typeof<'b> = typeof<'c> with
        | true -> 
            let g1 : 'b -> 'd =
                // 运行时强制转换不被允许
                // 部分类型不支持运行时类型测试
                fun b -> g (b :?> 'c)
            Some (f >> g1)
        | false -> 
            None

2. 类型测试实现(编译报错)

尝试直接对函数做类型测试,但编译时报错:

type Composer() = 
    member _.Compose<'a,'b,'c,'d> (f : 'a -> 'b,g : 'c -> 'd) : ('a -> 'd) option =
        if (g :? ('b -> 'd)) then
            Some (f >> (g :?> ('b -> 'd)))
        else 
            None

错误信息:

the type 'c -> 'd does not have any proper subtypes and cannot 
be used as the source of a type test or runtime coercion

困惑点

按逻辑,类型本身应该是自身的子类型,但F#类型系统却提示仅接受“合适子类型”。而对应的C#实现却能正常工作,符合预期。


可行的C#实现

static Func<A,D>? Compose<A,B,C,D>(Func<A,B> f,Func<C,D> g)
{
    var g1 = g as Func<B, D>;
    if (g1 == null)
    {
        return null;
    }
    else
    {
        return (A a) => g1(f(a));
    }
            
}

[Fact]
public void ComposeTest()
{
    Func<int,int> f = x => x + 1;
    Func<int, string> g = x => x.ToString();

    var foo = Compose(f,g);
    var bar = Compose(g,f);

    foo(1);
}

寻求解决方案

需要实现符合需求的F#函数组合器。

内容的提问来源于stack exchange,提问作者MrD at KookerellaLtd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 22:27:43