Code Monkey home page Code Monkey logo

Comments (2)

dvdsgl avatar dvdsgl commented on July 27, 2024

How about something like this:

module Options where

-- 'Options' is some opaque foreign type that holds a heterogeneous collection of `Option a`
foreign import data Options :: Type

foreign import optionsEmpty :: Options
foreign import optionsAdd :: forall a. Options -> Option a -> Options
foreign import optionsGet :: forall a. Options -> String -> Maybe (Option a)

data OptionKind
    = Boolean
    | String
    | Choice (Array String)

type Option a =
    { kind :: OptionKind
    , value :: Json -- this is foreign data that should be an `a` but we don't assume it is
    , default :: a
    , label :: String
    }

-- We use this from JavaScript to put values into options
-- Storing an invalid value will cause the Option to revert to its default value
setValueFromJS :: forall a. Option a -> Json -> Option a
setValueFromJS opt v = opt { value = v }

booleanOption :: String -> Boolean -> Option Boolean
booleanOption label default =
    { kind: Boolean
    , value: fromBoolean default
    , default
    , label
    }

-- An example option
renderProperties :: Option Boolean
renderProperties = booleanOption "Render Properties" true

class OptionValue a where
  getValue :: Option a -> Maybe a
  setValue :: Option a -> a -> Option a

instance optionValueBoolean :: OptionValue Boolean where
  getValue { value } = toBoolean value
  setValue opt b = opt { value = fromBoolean b }

-- Helpers for reading Options
getValueOrDefault :: forall a. Option a -> a
getValueOrDefault opt@{ default } = fromMaybe default $ getValue opt

getOption :: forall a. Options -> Option a -> Maybe (Option a)
getOption opts { label } = optionsGet opts label

getOptionOrDefault :: forall a. Options -> Option a -> a
getOptionOrDefault opts opt@{ default } = fromMaybe default $ getOption opts opt

-- Nice, but definitely not necessary
infixr 5 getOptionOrDefault as ~>

-- Later when we have an `options :: Options` coming from the CLI or web app:
let shouldRender = options ~> renderProperties

Then in Options.js:

exports.optionsEmpty = [];

exports.optionsAdd = function (opts) {
  return functions (opt) {
    opts.push(opt);
  };
};

...

from quicktype.

schani avatar schani commented on July 27, 2024

Implemented in b91eff8

from quicktype.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.