只是试着绕过一些F#,我遇到了问题。
我有一个类似
的CSV文件CorrelationId,TagNumber,Description,CreationDate,UpdateDate,Discipline
8D3F96F3-938F-4599-BCA1-66B13199A39A,Test 70-2,Test tag - Ignore,2016-04-05 14:55:23.503,2016-04-05 14:55:23.503,Mechanical
A9FD4B9D-F7A1-4B7D-917F-D633EA0321E3,test-4,A test tag 24,2016-03-23 15:09:54.667,2016-03-30 17:35:29.553,Civil
我正在使用CSV类型提供程序
阅读它open FSharp.Data
type Tag = CsvProvider<"tags.csv">
let readTags (path:string) =
let tags = Tag.Load(path)
printfn "%i" ( tags.Rows |> Seq.length )
let tag = tags.Rows |> Seq.head
然后我想验证行,所以我从fsharpforfunandprofit铁路导向编程中提示。
type Result<'TSuccess,'TFailure> =
| Success of 'TSuccess
| Failure of 'TFailure
let bind switchFunction twoTrackInput =
match twoTrackInput with
| Success s -> switchFunction s
| Failure f -> Failure f
let validateTagName tag =
if String.length tag.TagNumber = 0 then Failure "Tag number cannot be empty"
else Success tag
let validateTagDescription tag =
if String.length tag.Description = 0 then Failure "Tag description cannot be empty"
else Success tag
但是我在验证方法中遇到了一个问题,我需要用类型注释函数。我不知道注释这些类型的类型。我尝试使用创建新类型并映射到它
type tagType = { TagNumber: string; Description: string}
这使得这些函数可以正常编译,但我刚刚将问题解决了,因为现在我不确定如何从Tag.Row映射到tagType。理想情况下,我无需进行任何映射即可进行此验证。
这一切应该怎么样?
答案 0 :(得分:5)
您已从类型提供程序中获得Tag
类型。使用该特定数据样本,它提供了一个名为Tag.Row
的嵌套类型。您可以使用该类型注释您的函数:
let validateTagName (tag : Tag.Row) =
if String.length tag.TagNumber = 0 then Failure "Tag number cannot be empty"
else Success tag
let validateTagDescription (tag : Tag.Row) =
if String.length tag.Description = 0 then Failure "Tag description cannot be empty"
else Success tag
这些函数编译。
答案 1 :(得分:3)
要添加Mark的答案,问题是以OOP方式打入一个类通常需要一个类型注释, 因为类型推断通常无法分辨出正在使用的类型。
例如,x
的类型是什么?
let doSomething x = x.Length // error FS0072: Lookup on object of indeterminate type
使用附加到模块的函数可以为类型推断提供所需的信息:
let doSomething x = List.length x // Compiles OK
类型推断通常适用于您定义的记录类型:
type tagType = { TagNumber: string; Description: string}
let doSomething x = x.TagNumber // Compiles OK
但是在这种情况下,您正在使用由类型提供程序定义的类,因此类型推断也不起作用。
正如马克所说,最简单的方法是按照他演示的方式使用类型注释。
另一种方法是将类型提供程序Tag
类型的转换函数写入您自己的MyTag
类型,然后执行
let myTags = tags.Rows |> Seq.map convertToMyTag
将每一行转换为您的类型。当我想要一个更复杂的域类型而不仅仅是一个带字段的简单记录时,我有时会这样做。
在这种情况下,这将是过度的(你仍然需要在转换器函数中添加注释!)
最后,这里有两篇可能有用的帖子:understanding type inference 和troubleshooting common compiler errors。