dynamic: A dynamic type for Haskell

[ bsd3, development, library ] [ Propose Tags ]

Want to do dynamically typed programming in Haskell sometimes? Here you go!


[Skip to Readme]

Modules

[Last Documentation]

  • Dynamic

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.0.1, 0.0.2, 0.0.3, 0.0.4, 0.0.5, 0.0.6, 0.0.7, 0.1.0
Dependencies aeson, aeson-pretty, base (>=4.7 && <5), bytestring, cassava, containers, text, unordered-containers, vector [details]
License BSD-3-Clause
Copyright 2019 Chris Done
Author Chris Done
Maintainer chrisdone@gmail.com
Category Development
Home page https://github.com/chrisdone/dynamic#readme
Source repo head: git clone https://github.com/chrisdone/dynamic
Uploaded by ChrisDone at 2019-03-31T15:35:33Z
Distributions NixOS:0.1.0
Downloads 3530 total (26 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs not available [build log]
All reported builds failed as of 2019-03-31 [all 3 reports]

Readme for dynamic-0.0.1

[back to package description]

dynamic

Finally, dynamically typed programming in Haskell made easy!

Introduction

Tired of making data types in your Haskell programs just to read and manipulate basic JSON/CSV files? Tired of writing imports? Use dynamic, dynamically typed programming for Haskell!

Load it up

Launch ghci, the interactive REPL for Haskell.

import Dynamic

Now you're ready for dynamicness!

Make dynamic values as easy as pie!

Primitive values are easy via regular literals:

> 1
1
> "Hello, World!"
"Hello, World!"

Arrays and objects have handy functions to make them:

> fromList [1,2]
[
    1,
    2
]
> fromDict [ ("k", 1), ("v", 2) ]
{
    "k": 1,
    "v": 2
}

Get object keys or array or string indexes via !:

> fromDict [ ("k", 1), ("v", 2) ] ! "k"
1
> fromList [1,2] ! 1
2
> "foo" ! 2
"o"

Web requests!

> chris <- getJson "https://api.github.com/users/chrisdone"
> chris
{
    "bio": null,
    "email": null,
    "public_gists": 176,
    "repos_url": "https://api.github.com/users/chrisdone/repos",
    "node_id": "MDQ6VXNlcjExMDE5",
    "following_url": "https://api.github.com/users/chrisdone/following{/other_user}",
    "location": "England",
    "url": "https://api.github.com/users/chrisdone",
    "gravatar_id": "",
    "blog": "https://chrisdone.com",
    "gists_url": "https://api.github.com/users/chrisdone/gists{/gist_id}",
    "following": 0,
    "hireable": null,
    "organizations_url": "https://api.github.com/users/chrisdone/orgs",
    "subscriptions_url": "https://api.github.com/users/chrisdone/subscriptions",
    "name": "Chris Done",
    "company": "FP Complete @fpco ",
    "updated_at": "2019-02-22T11:11:18Z",
    "created_at": "2008-05-21T10:29:09Z",
    "followers": 1095,
    "id": 11019,
    "public_repos": 144,
    "avatar_url": "https://avatars3.githubusercontent.com/u/11019?v=4",
    "type": "User",
    "events_url": "https://api.github.com/users/chrisdone/events{/privacy}",
    "starred_url": "https://api.github.com/users/chrisdone/starred{/owner}{/repo}",
    "login": "chrisdone",
    "received_events_url": "https://api.github.com/users/chrisdone/received_events",
    "site_admin": false,
    "html_url": "https://github.com/chrisdone",
    "followers_url": "https://api.github.com/users/chrisdone/followers"
}

Trivially read CSV files!

> fromCsvNamed "name,age,alive,partner\nabc,123,true,null\nabc,ok,true,true"
[{
    "alive": true,
    "age": 123,
    "partner": null,
    "name": "abc"
},{
    "alive": true,
    "age": "ok",
    "partner": true,
    "name": "abc"
}]

Dynamically typed programming!

Just write code like you do in Python or JavaScript:

> if chris!"followers" > 500 then chris!"public_gists" * 5 else chris!"name"
880

Experience the wonders of dynamic type errors!

Try to treat non-numbers as numbers and you get the expected result:

> map (\o -> o ! "age" * 2) $ fromCsvNamed "name,age,alive,partner\nabc,123,true,null\nabc,ok,true,true"
[246,*** Exception: DynamicTypeError "Couldn't treat string as number: ok"

Laziness makes everything better!

> map (*2) $ toList $ fromJson "[\"1\",true,123]"
[2,*** Exception: DynamicTypeError "Can't treat bool as number."

Woops...

> map (*2) $ toList $ fromJson "[\"1\",123]"
[2,246]

That's better!

Modifying and updating records

Use modify or set to massage data into something more palatable.

> modify "followers" (*20) chris
{
    "bio": null,
    "email": null,
    "public_gists": 176,
    "repos_url": "https://api.github.com/users/chrisdone/repos",
    "node_id": "MDQ6VXNlcjExMDE5",
    "following_url": "https://api.github.com/users/chrisdone/following{/other_user}",
    "location": "England",
    "url": "https://api.github.com/users/chrisdone",
    "gravatar_id": "",
    "blog": "https://chrisdone.com",
    "gists_url": "https://api.github.com/users/chrisdone/gists{/gist_id}",
    "following": 0,
    "hireable": null,
    "organizations_url": "https://api.github.com/users/chrisdone/orgs",
    "subscriptions_url": "https://api.github.com/users/chrisdone/subscriptions",
    "name": "Chris Done",
    "company": "FP Complete @fpco ",
    "updated_at": "2019-02-22T11:11:18Z",
    "created_at": "2008-05-21T10:29:09Z",
    "followers": 21900,
    "id": 11019,
    "public_repos": 144,
    "avatar_url": "https://avatars3.githubusercontent.com/u/11019?v=4",
    "type": "User",
    "events_url": "https://api.github.com/users/chrisdone/events{/privacy}",
    "starred_url": "https://api.github.com/users/chrisdone/starred{/owner}{/repo}",
    "login": "chrisdone",
    "received_events_url": "https://api.github.com/users/chrisdone/received_events",
    "site_admin": false,
    "html_url": "https://github.com/chrisdone",
    "followers_url":
    "https://api.github.com/users/chrisdone/followers"
}

List of numbers?

The answer is: Yes, Haskell can do that!

> [1.. 5] :: [Dynamic]
[1,2,3,4,5]

Coming soon

Monoid instances so we can append Dynamics together!