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 905565
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T16:14:33+00:00 2026-05-15T16:14:33+00:00

I’m trying to write a function that accepts a certain type or any of

  • 0

I’m trying to write a function that accepts a certain type or any of its sub-types as one of its arguments, then returns a value of a type or any of its sub-types.

[<AbstractClass>]
type Spreader () =
    abstract Fn : unit -> unit

type Fire () =
    inherit Spreader ()
    override self.Fn () = ()

type Disease () =
    inherit Spreader ()
    override self.Fn () = ()

let spread (spr:#Spreader) : #Spreader =
    match spr with
    | :? Fire -> Fire ()
    | :? Disease -> Disease ()
    | _ -> failwith "I don't get it"

Obviously, this doesn’t work but you get what I’m trying to do.

At first, I implemented an abstract function in the Spreader type and overrode (overrided?) it in the sub-types, but that required upcasting, which I’m trying to avoid.

Is this doable? I’m looking into generics, but I’ve not quite got a grasp on their F# implementation.

EDIT 2010.07.08 1730 PST

Regarding the suggestion that I use discriminated unions, I’d tried that before. The problem I ran into was that any function that I defined as a member of the base type had to process every branch of the union. For example:

type strength = float32

type Spreader =
    | Fire of strength
    | Disease of strength

    member self.Spread () =
        match self with
        | Fire str -> Fire str
        | Disease str -> Disease str

    member self.Burn () =
        match self with
        | Fire str -> Fire str
        | _ -> failwith "Only fire burns"

The Spread function works fine here, but if I want Fire to Burn, then I have to provide for Disease, too, which makes no sense.

I want to allow for possible attempts by the user to do something illegal like trying to Disease.Burn, but I don’t want to have to return a bunch of option types all over the place, e.g.:

member self.Burn () =
    match self with
    | Fire str -> Some(Fire str)
    | _ -> None

I’d rather just leave the Burn function strictly to the Fire Spreader, and not even have it defined for the Disease Spreader.

Furthermore, this goes for properties, too; there are some members that I want Fire to have that don’t make sense for Disease, and vice versa. Also, I’d like to be able to access a Spreader’s strength value using dot notation, since I’m going to have other members that I access that way anyway, and it seems curiously redundant to have to define member.strength after it’s already encapsulated in the object. ( e.g. | Disease str -> …)

Another option, of course, is to simply separate the Spread and Burn functions from the Spreader type, but then I have to either (1) supply ugly upcasting or generics code for the functions (as others have described), or (2) have totally separate functions for Fire and Disease, which would suck in the case of Spread as I’d have to name them SpreadFire and SpreadDisease (since function overloading outside types is curiously not allowed).

As a noob to F#, I welcome all criticisms and suggestions. 🙂

EDIT 2010.07.09 0845 PST

Jon Harrop: “Why are you using augmentations and members?”

Because the types in my actual code are mathematics-intensive, so I’m precomputing certain values at initialization and storing them as members.

Jon Harrop: “Why do you want burn to apply to Speader types when it is only applicable to one?”

As I wrote, I don’t want Burn to apply to Spreader. I want it to apply solely to Fire. I was torn, however, between implementing the function as a member of Spreader, and separating it from the Spreader type. (Inconsistency smell.)

Jon Harrop: “What is the purpose of your Fn member?”

Sorry, that was just extraneous code, please ignore it.

Jon Harrop: “Why did you use an abstract class instead of an interface?”

Code readability and efficiency, mostly. I hate having to upcast to an interface just to use one of its methods.

Jon Harrop: “Why did you define strength as an alias for float32?”

Code readability.

Jon Harrop: “What is the actual concrete problem you are trying to solve?!”

Code sharing for related types, while maintaining readability.

Interestingly, the solution that you offered is exactly the solution that I first tried (I’ve been at this F# thing for only a week or so), but I discarded it because I was uncomfortable with the idea of having to wrap my fundamental types in a DU as a work-around for not being able to overload functions defined outside type definitions. I’m just really paranoid about getting off on the wrong foot with fundamental types (in part due to the lamentable lack of F# refactoring in VS2010). Functional programming is a subject of great interest to me right now, and I’m pretty much just fishing around for understanding.

EDIT 2010.07.09 2230 PST

Actually, I/m starting not to like functional programming (really agree with the author at http://briancarper.net/blog/315/functional-programming-hurts-me — if I see one more Fibonacci or factorial coding example in an F# tutorial or textbook, I’m going to stab the next nerd I find).

I was hoping that someone here would shoot back at my latest response (explaining why I am doing certain things) with the sort of scorn that Jon exhibited (below). I want to learn FP from the haughty elites, the coders who think their sh*t doesn’t stink.

  • 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-15T16:14:33+00:00Added an answer on May 15, 2026 at 4:14 pm

    You probably need to explicitly upcast your return values:

    let spread (spr: Spreader) =
      match spr with
      | :? Fire -> (Fire() :> Spreader)
      | :? Disease -> (Disease() :> Spreader)
    

    This is a very unusual programming style though. What exactly are you trying to do?

    EDIT

    I still don’t understand what you are trying to accomplish. Why are you using augmentations and members? Why do you want burn to apply to Speader types when it is only applicable to one? What is the purpose of your Fn member? Why did you use an abstract class instead of an interface? Why did you define strength as an alias for float32? What is the actual concrete problem you are trying to solve?!

    What about this:

    type fire = ...
    
    let burn fire = ...
    
    type spreader = Disease | Fire of fire
    
    let spread = function
      | Disease -> ...
      | Fire fire -> ...
    

    Basically, if you have functions that only apply to a subset of spreaders then you need to separate concerns somehow. Either by indirecting through new types (as above) or by using OOP and making the subset of classes implement an interface.

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

Sidebar

Ask A Question

Stats

  • Questions 459k
  • Answers 459k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer The tomcat instance should be set up to provide a… May 15, 2026 at 11:18 pm
  • Editorial Team
    Editorial Team added an answer First of all, create a NSURL. Then, use the querymethod… May 15, 2026 at 11:18 pm
  • Editorial Team
    Editorial Team added an answer Keep in mind syslog is a protocol, which means it… May 15, 2026 at 11:18 pm

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

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.