Reputation: 14417
So I have this last piece in a pipe
|> Array.iter (fun name -> name
|> transform
|> printfn "RENAME '%s' INTO '%s'" name )
The transform is:
let transform (text: string) =
text.Replace(" ", ".")
To me the iter
predicate function isn't very clear, it is saying push name into transform
then push the result in printfn
with the original name appended to it....
Is there a way to make the transformation pipe more intention revealing using pipe forward or backward operators.
I thought maybe
name
|> printfn "RENAME '%S' INTO '%S'"
<| transform
But obviously that doesn't work.
If it can't look nicer in the pipe then I guess it is the most succinct way - apart from making a a new function that combines the printfn in some fashion with the transform, but I wouldn't mind avoiding that...
I just want to make sure I'm not missing any straightforward syntax..
I don't think there is, because I'm facing a function that takes multiple arguments, in order to use it in a pipe forward it can only have 1 parameter, which is effectively what I'm doing by partial application.
Upvotes: 1
Views: 105
Reputation: 1188
This is kind of how I would go about this task:
let array = [|
"one"
"two"
"three"
|]
let transform s = s, s + "_transformed"
let printIt (n,t) = printfn "RENAME '%s' INTO '%s'" n t
array
|> Array.map transform
|> Array.iter printIt
My "best practice" tells me that I always should create and use functions. This way the flow (map and iter) is constant, and the functions or data may change.
Addendum to "clarify" WHY to use functions and what not
let myPipeLineWithPrint t p a=
a
|> Array.map t
|> Array.iter p
//"Old" Version With above data
myPipeLineWithPrint transform printIt array
type SomeRecord = {
Name: string
MoreStuff: string
}
type OtherRecord = {
NewName: string
OldName: string
}
let array2 = [|
{Name="one"; MoreStuff="dontcare"}
{Name="two"; MoreStuff="dontcare"}
{Name="three"; MoreStuff="dontcare"}
|]
let transform2 {Name=n; MoreStuff=ms} = transform n
myPipeLineWithPrint transform2 printIt array2
let transform3 {Name=n; MoreStuff=_} =
let (_,nn) = transform n
{NewName= nn; OldName=n}
let printIt2 {NewName=nn; OldName = o} = printfn "RENAME '%s' INTO '%s'" o nn
myPipeLineWithPrint transform3 printIt2 array2
Upvotes: 1
Reputation: 2395
Sometimes it is better to avoid unnecessary piping as it can obfuscate the code. Your function simply prints as follows:
printfn "RENAME '%s' INTO '%s'" name (transform name)
And you can omit parens by using <|
:
printfn "RENAME '%s' INTO '%s'" name <| transform name
And that looks better IMHO.
Upvotes: 4
Reputation: 4770
Maybe skipping the pipe is more clear in this case?
|> Array.iter (fun name -> printfn "RENAME '%s' INTO '%s'" name (transform name))
Also note that your original predicate can be composed further like so:
|> Array.iter (transform >> printfn "RENAME '%s' INTO '%s'" name)
Which can be written like this if you want the transform to come last:
|> Array.iter ((printfn "RENAME '%s' INTO '%s'" name) << transform)
Upvotes: 2