简体   繁体   中英

Augmenting type aliases in elm or haskell

Say I have a type in elm (0.18) like this:

type alias CatSimple = 
  { color : String
  , age : Int 
  , name : String
  , breed : String
}

My project requires that I also have a type that has all the fields of the previous one, but with a few additional fields:

type alias CatComplex =
  { color : String
  , age : Int 
  , name : String
  , breed : String
  , feral : Bool
  , spayed : Bool
} 

Now let's say that I need to add another field to CatSimple . I would have to remember to add it to CatComplex as well.

I would like to be able to dynamically augment my types so that I can avoid having to update all of them, or having to resort to something like this:

type alias CatComplex =
  { simpleData: CatSimple
  , feral : Bool
  , spayed : Bool
} 

Is there any way to do that in Elm?

If not, does Haskell provide a way to do this?

You can use extensible records in Elm to define a rudimentary sort of field composition:

type alias Cat c =
    { c
        | color : String
        , age : Int
        , name : String
        , breed : String
    }

type alias FeralCat =
    Cat
        { feral : Bool
        , spayed : Bool
        }

Here's an example of how it could be used:

feralCatSummary : FeralCat -> String
feralCatSummary { color, feral } =
    color ++ "; Feral? " ++ toString feral

main : Html msg
main =
    text <|
        feralCatSummary
            { color = "Blue"
            , age = 5
            , name = "Billy"
            , breed = "Bluecat"
            , feral = True
            , spayed = False
            }

The short answer is no, but there are some things you can do that go in the direction you want:

Have a single type but make the extra info 'optional'

type alias Cat =
  { color : String
  , age : Int 
  , name : String
  , breed : String
  , feral : Maybe Bool
  , spayed : Maybe Bool
 } 

When you want to pass CatComplex to a function that only uses the Cat fields you could define a Type

 type alias CatGeneric a =       
    { a| 
          color : String
          , age : Int 
          , name : String
          , breed : String 
      }

then

fn : CatGeneric a -> Bool 
....

and this should type check if you pass either a Cat or a CatComplex

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM