I am trying to build a list from the names of some files. Unfortunately I am getting a type error that I do not know how to correct.
My code:-
open System
let buildStringList (list: string []) =
let initial = []
for i = 0 to list.Length do
let foo = list.[i]
List.append initial foo.Substring(foo.IndexOf("."))
The type error:-
error FS0001: This expression was expected to have type string -> 'a
but here has type string
And this relates to the "foo.Substring(foo.IndexOf("."))" object. What is the best way to get the types correct here?
Many thanks.
Indentation of your function is totally off. At any rate, foo.Substring(foo.IndexOf("."))
is a string
which isn't of type list
as required by List.append
.
What you want is to add an element to an accumulator list. A quick fix on your function is using a mutable
value:
let buildStringList (arr: string []) =
let mutable result = []
for i = 0 to arr.Length do
let foo = arr.[i]
result <- foo.Substring(foo.IndexOf("."))::result
List.rev result // Use List.rev if you would like to keep the original order
However, the recommended way is to use high-order functions. While using List.map
as Mark's answer is a good approach, you can use Array.fold
which is closer to your code:
let buildStringList (arr: string []) =
arr
|> Array.fold (fun acc foo -> foo.Substring(foo.IndexOf("."))::acc) []
|> List.rev
To be complete, list comprehension is also helpful in certain situations:
let buildStringList (arr: string []) =
[ for foo in arr -> foo.Substring(foo.IndexOf(".")) ]
I think this is a more functional way to do what you're trying:
open System
let buildStringList (list: string []) =
list |> Array.toList |> List.map (fun x -> x.Substring(x.IndexOf(".")))
The reason for your particular error was that List.append takes two lists, not a list and a single item.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.