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

  • Home
  • SEARCH
  • 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 8487237
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T21:10:51+00:00 2026-06-10T21:10:51+00:00

I’m attempting to implement a fold over a discriminated union. The DU is called

  • 0

I’m attempting to implement a fold over a discriminated union. The DU is called Expr, and represents a program expression, and is often recursive. I’m attempting to write a fold that accumulates the result of an operation over the Exprs recursively. Below is my attempt to write the fold.

let rec foldProceduralExpr (folder : 's -> Expr list -> 's) (state : 's) (expr : Expr) : 's =
    let children =
        match expr with
        | Series s -> s.SerExprs
        | Lambda l -> [l.LamBody; l.LamPre; l.LamPost]
        | Attempt a -> a.AttemptBody :: List.map (fun ab -> ab.ABBody) a.AttemptBranches
        | Let l -> l.LetBody :: List.concat (List.map (fun lb -> match lb with LetVariable (_, expr) -> [expr] | LetFunction (_, _, body, _, pre, post, _) -> [body; pre; post]) l.LetBindings)
        | Case c -> c.CaseTarget :: List.concat (List.map (fun branch -> [branch.TBBody; branch.TBTest]) c.CaseBranches)
        | Condition c -> List.concat (List.map (fun branch -> [branch.TBBody; branch.TBTest]) c.CondBranches)
        | List l -> l.ListElements
        | Array a -> Array.toList a.ArrElements
        | Composite c -> LunTrie.toValueList (LunTrie.map (fun _ mem -> mem.MemExpr) c.CompMembers)
        | _ -> []
    let listFolder = fun state expr -> foldProceduralExpr folder state expr
    let listFolded = List.fold listFolder state children
    folder state (expr :: listFolded)

The problem is that the code doesn’t work, and this is known because I get the error the construct causes code to be less generic than indicated by the type annotations. The type variable 's has been constrained to be type 'Expr list' on listFolded on the last line. This is because the definition of foldProceduralExpr is almost certainly wrong.

Now, I’d love to fix the code and consequently the type error, but I simply don’t know how. I suppose what I lack is an understanding in how folds over non-list or recursive data structures work. I recently translated a fold for a trie from OCaml to F#, and had a lot of trouble understanding how that fold worked as well.

Question 1: Is there a visible fix for this code that I can just understand slap in?

Question 2: Is there a resource for gaining the background needed to understand how to write these type of folds?

Please let me know if you need more information. I’ve not included the DU as it’s too big and complicated to keep the question clear. Hopefully suffice to say, it’s your typical Lisp-style AST data structure.

Follow up question: I’d also like to write a map with that fold once it works. Would that look like a typical map, or would that take some extra brain-power to figure out too?

EDIT: With regards to Tomas’ help, I’ve turned the last three lines into –

let exprs = expr :: children
let listFolder = fun state expr -> foldProceduralExpr folder state expr
let listFolded = List.fold listFolder state exprs
folder listFolded exprs

I hope this still makes sense.

EDIT: Here’s my final solution. It’s generalized over get children –

let rec foldRdu (getChildren : 't -> 't list) (folder : 's -> 't -> 't list -> 's) (state : 's) (parent : 't) : 's =
    let children = getChildren parent
    let listFolder = fun state child -> foldRdu getChildren folder state child
    let listFolded = List.fold listFolder state children
    folder listFolded parent children

The reason I’m taking an Expr and Expr list as the fold value it that I want to preserve the structure of the parent / children relationship to use later. This is a very domain-specific fold, in a way I suppose.

  • 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-06-10T21:10:52+00:00Added an answer on June 10, 2026 at 9:10 pm

    The first question is, what kind of fold do you want to implement? There is a number of options for tree-like structures. Assuming you have an n-ary tree (that is, any number of children), you can:

    1. Apply the folding function only on Expr nodes in the leafs
    2. Apply the folding function on the leafs and then apply it to all internal nodes (after a recursive call)
    3. Apply the folding function on the internal nodes while processing the tree and then on leafs

    In your example, your folder function takes Expr list which is a bit confusing to me – I would think you could just give it the current Expr and not a list of children, but calling it on children is an option too.

    You’re first making a recursive call and then calling the folder on current expression, so I suppose you wanted to implement the option 2. I can understand the first two lines of your folding:

    // This defines a function that recursively folds the a given 
    // expression and produces a new state of type 's
    let listFolder = fun state expr -> foldProceduralExpr folder state expr 
    // Here, you fold all children recursively starting with 'state' and 
    // obtaining a result 'listFolded' of type 's
    let listFolded = List.fold listFolder state children 
    

    However, the last line is probably wrong:

    // From the previous line, 'listFolded' is of type 's, but 
    // here you use it as if it was a list:
    folder state (expr :: listFolded) 
    

    I assume you probably want to use listFolded as the state passed to the folder. The folder takes a list of expressions, so you can give it children as the second argument (or you can change folder to take just a single Expr and then give it just expr, which would IMHO make more sense). Anyway, this should make it work, so that you can run it and see what is going on:

    folder listFolded children
    
    • 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
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
I would like to count the length of a string with PHP. The string
For some reason, after submitting a string like this Jack’s Spindle from a text
I am trying to understand how to use SyndicationItem to display feed which is

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.