Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6846315
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T00:36:23+00:00 2026-05-27T00:36:23+00:00

I’ working on a basic 2D CAD engine and the pipeline operator significantly improved

  • 0

I’ working on a basic 2D CAD engine and the pipeline operator significantly improved my code. Basically several functions start with a point (x,y) in space and compute a final position after a number of move operations:

let finalPosition =
    startingPosition
    |> moveByLengthAndAngle x1 a1 
    |> moveByXandY x2 y2
    |> moveByXandAngle x3 a3
    |> moveByLengthAndAngle x4 a4
    // etc...

This is incredibly easy to read and I’d like to keep it that way. The various x1, a1, etc. obviously have a meaning name in the real code.

Now the new requirement is to introduce exception handling. A big try/with around the whole operation chain is not enough because I’d like to know which line caused the exception. I need to know which argument is invalid, so that the user knows what parameter must be changed.

For example if the first line (moveByLengthAndAngle x1 a1) raises an exception, I’d like to tell something like “Hey, -90 is an invalid value for a1! a1 must be between 45 and 90!”. Given that many operations of the same type can be used in the sequence it’s not enough to define a different exception type for each operation (in this example I wouldn’t be able to tell if the error was the first or the last move).

The obvious solution would be to split the chain in single let statements, each within its respective try/with. This however would make my beautiful and readable code a bit messy, not so readable anymore.

Is there a way to satisfy this requirement without sacrificing the readability and elegance of the current code?

(note. right now every moveBy function raises an exception in case of errors, but I’m free to change for ex. to return an option, a bigger tuple, or just anything else if needed).

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T00:36:24+00:00Added an answer on May 27, 2026 at 12:36 am

    How about folding over Choices? Let’s say that instead of pipelining the actions, you represent them like this:

    let startingPosition = 0. ,0.
    
    let moveByLengthAndAngle l a (x,y) = x,y // too lazy to do the math
    let moveByXandY dx dy (x,y) = 
        //failwith "oops"
        x+dx, y+dy
    let moveByXandAngle dx a (x,y) = x+dx, y
    
    let actions = 
        [
            moveByLengthAndAngle 0. 0., "failed first moveByLengthAndAngle"
            moveByXandY 1. 2., "failed moveByXandY"
            moveByXandY 3. 4., "failed moveByXandY"
            moveByXandAngle 3. 4., "failed moveByXandAngle"
            moveByLengthAndAngle 4. 5., "failed second moveByLengthAndAngle"
        ]
    

    i.e. actions is of type ((float * float -> float * float) * string) list.

    Now, using FSharpx we lift the actions to Choice and fold/bind (not sure how to call it this is similar to foldM in Haskell) over the actions:

    let folder position (f,message) =
        Choice.bind (Choice.protect f >> Choice.mapSecond (konst message)) position
    
    let finalPosition = List.fold folder (Choice1Of2 startingPosition) actions
    

    finalPosition is of type Choice<float * float, string> , i.e. it’s either the final result of all those functions, or an error (as defined in the table above).

    Explanation for this last snippet:

    • Choice.protect is similar to Tomas’ protect, except that when it finds an exception, it returns the exception wrapped in a Choice2Of2. When there’s no exception, it returns the result wrapped in a Choice1Of2.
    • Choice.mapSecond changes this potential exception in Choice2Of2 with the error message defined in the table of actions. Instead of (konst message) this could also be a function that builds the error message using the exception.
    • Choice.bind runs this “protected” action against the current position. It will not run the actual action if the current position is in error (i.e. a Choice2Of2).
    • Finally, the fold applies all actions threading along / accumulating the resulting Choice (either the current position or an error).

    So now we just have to pattern match to handle each case (correct result or error):

    match finalPosition with
    | Choice1Of2 (x,y) -> 
        printfn "final position: %f,%f" x y
    | Choice2Of2 error -> 
        printfn "error: %s" error
    

    If you uncomment failwith "oops" above, finalPosition will be a Choice2Of2 "failed moveByXandY"

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
Basically, what I'm trying to create is a page of div tags, each has
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
Specifically, suppose I start with the string string =hello \'i am \' me And
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I'm working with an upstream system that sometimes sends me text destined for HTML/XML
I have this code to decode numeric html entities to the UTF8 equivalent character.
I ran into a problem. Wrote the following code snippet: teksti = teksti.Trim() teksti
That's pretty much it. I'm using Nokogiri to scrape a web page what has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.