如何修复无法将Result <SuccessType <A>,Error>类型的值转换为关闭结果类型Result <Success,Failure> Swift

时间:2019-08-30 22:32:49

标签: swift generics closures

我正在尝试映射Swift的Result类型以产生其他类型的新Result,但这不是类型检查,并且会引发错误:

error: cannot convert value of type Result<ParseSuccess<B>, ParseError> to closure result type Result<Success, Failure>

我尝试在结果上使用开关,并在.success和.failure上进行匹配,但是出现类似的类型检查错误。我也尝试过明确指定输入和返回类型,但是没有运气。

我已经用我更熟悉的其他语言(F#和Kotlin)复制了代码,并且似乎在其中键入了check。

swift编译器在此行下显示一个小字: return self.apply(input).map { result in ParseSuccess(transform(result.data), result.input) }

此代码在哪里出问题?

import Foundation

class ParseError : Error {
    let err: String
    init(_ err: String) {
        self.err = err
    }
}

class ParseSuccess<A> {
    let data: A
    let input: Substring

    init(_ data: A, _ input: Substring) {
        self.data = data
        self.input = input
    }
}

class Parser<A> {
    let fn: (Substring) -> Result<ParseSuccess<A>, ParseError>

    init(_ fn: @escaping (Substring) -> Result<ParseSuccess<A>, ParseError>) {
        self.fn = fn
    }

    func apply(_ input: Substring) -> Result<ParseSuccess<A>, ParseError> {
        return self.fn(input)
    }

    func map<B>(_ transform: @escaping (A) -> B) -> Parser<B> {
        return Parser { (input) in 
            return self.apply(input).map { result in 
 ParseSuccess(transform(result.data), result.input) }
        }
    }      
}

对于它的价值,我敢肯定这可能不是开始编写解析器组合器的最佳方法,但是我已经陷入尝试找出我在这里出了错的地方了!

谢谢

1 个答案:

答案 0 :(得分:0)

这是Paraser行中return Parser {的不合格用法的怪异行为。当泛型类型以其非限定形式被提及时,在泛型类型的声明主体内,类型参数被推断为未更改。例如,Array<T>上的一个函数可以简单地返回Array,并且T隐含与T的{​​{1}}的值相同。说,我不是这种行为的忠实拥护者。

将其更改为self.可解决此问题。


这是我发现问题的方式。处理泛型错误时,我总是尝试插入大量类型注释以“固定”数据类型,以确认编译器和我位于同一页面上。

我首先写道:

return Parser<B> { ...

此时错误变为:

func map<B>(_ transform: @escaping (A) -> B) -> Parser<B> {
    return Parser { (input) in 
        return self.apply(input).map { result in 
            let newData: ParseSuccess<B> = transform(result.data)
            return ParseSuccess(newData, result.input)
        }
    }
}