Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Based on the following:</p> <p><a href="https://stackoverflow.com/questions/16016087/strange-behavior-of-f-records">Strange behavior of F# records</a> :</p> <blockquote> <p>It is important to realize that F# does not use structural typing (meaning that you cannot use record with more fields as an argument to a function that takes record with fewer fields). This might be a useful feature, but it does not fit well with .NET type system. This basically means you cannot expect too fancy things - the argument has to be a record of a well known named record type.</p> </blockquote> <p>nicolas:</p> <blockquote> <p>If you truly dont know beforehand which part of Large fn will use, then you have to give it all. this is the only semantically correct choice.</p> </blockquote> <p>I have come up with two possible solutions:</p> <p><strong>Solution 1</strong> </p> <p>I basically split the user function into two. The nice thing is that <code>reducedPostprocessFn</code> accepts only what it needs. This function is therefore easy to reason about and unit test. <code>postprocessFn</code> is so short that it is also simple to see what it does. I find this solution similar to active patterns presented by <code>Phillip Trelford</code>. I wonder what the advantage of active patterns is?</p> <pre><code>(* simulation *) type Large = {v1: int; v2: int} let simulation postprocessFn = let large = {v1 = 1; v2 = 2} postprocessFn large (* user *) let reducedPostprocessFn (v1: int) = printfn "%d" v1 let postprocessFn (large: Large) = reducedPostprocessFn large.v1 simulation postprocessFn </code></pre> <p><strong>Solution 2</strong></p> <p>This solution uses duck typing but:</p> <p><a href="http://msdn.microsoft.com/en-us/library/dd233203.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/dd233203.aspx</a></p> <blockquote> <p>Explicit Member Constraint: ... not intended for common use.</p> </blockquote> <p><a href="https://stackoverflow.com/questions/7065939/f-and-duck-typing">F# and duck-typing</a></p> <blockquote> <p>I just remembered this won't work for record types. Technically their members are fields, although you can amend them with members using with member .... </p> </blockquote> <p>So I used an ordinary class instead of records. Now I use only one function instead of two but, to be honest, duck typing in F# is just ugly.</p> <pre><code>(* simulation *) type Large(v1, v2) = member o.v1 = v1 member o.v2 = v2 let simulation postprocessFn = let large = Large(1, 2) postprocessFn large (* user 2 *) let inline postprocessFn small = let v = (^a: (member v1: int) small) printfn "%d" v simulation postprocessFn </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload