2010-11-25 11 views
25

En F # interactiva, que puede utilizar String.Join("+", ["a"; "b"]) con éxito, peroF #: string.join y |> operador

["a"; "b"] |> String.Join "+" 

produce un error:

Script1.fsx(79,15): error FS0001: This expression was expected to have type 
    string list -> 'a  
but here has type 
    string 

¿Cómo se utiliza String.Join pasar una colección usando ¿tubería?

P.S. El mismo problema es con lines |> File.WriteAllLines "filename.txt"

Respuesta

43

String.Join es un método .NET. Al usar un método .NET, F # lo ve como una función que toma una tupla como argumento (cuando lo llama, escribe parámetros como f(a, b)). El operador |> se puede usar con funciones que usan el formulario cursado de parámetros (y puede llamarse escribiendo f a b).

Usted puede utilizar una función String.concat de la biblioteca # F (que hace lo mismo) en su lugar:

["a"; "b"] |> String.concat "+" 

EDITARFile.WriteAllLines es el mismo caso. Si desea utilizarlo como parte de una tubería, se puede escribir una función # F que envuelve la llamada:

let writeAllLines file (lines:seq<string>) = 
    System.IO.File.WriteAllLines(file, lines) 

En general, se puede utilizar |> con métodos .NET sólo si desea escribir todos los argumentos de el lado izquierdo del operador. Puede, por ejemplo, escribir:

("+", ["a"; "b"]) |> System.String.Join 

... pero eso no encaja con el uso habitual del operador de tuberías. Cuando se trabaja con la API .NET, generalmente es mejor usar un estilo de programación similar a C# (sin canalización), porque la canalización solo funciona bien con bibliotecas funcionales.

+0

¡Gracias! Por cierto, ¿hay algo de suerte con 'File.WriteAllLines'? –

+0

o ... cualquier método .Net no funcionará con '|>'? –

+0

@modosansreves: He agregado respuestas a sus otras preguntas. –

10

Pensé en sopesar con una alternativa. El OP preguntó específicamente sobre String.Join, y la respuesta de Tomas Petricek es absolutamente correcta para ese método (use String.concat de la biblioteca F #).

Si estamos hablando de otro método que toma argumentos tupled pero que desea utilizarlos como curry, puede utilizar esta función auxiliar:

let partial f x y = f(x, y) 

Esto le permite pasar de un método de 'parcial' y recuperar una función al curry. Úselo así:

let partial f x y = f(x, y) 
myCollection |> partial String.Join "&"