All Projects → chrisdone → Dynamic

chrisdone / Dynamic

Licence: other
Dynamic typing in Haskell

Programming Languages

haskell
3896 projects

Labels

Projects that are alternatives of or similar to Dynamic

Wordpress Sdk
Stars: ✭ 162 (-15.18%)
Mutual labels:  analytics
Vue Matomo
Vue plugin for Piwik / Matomo Analytics
Stars: ✭ 168 (-12.04%)
Mutual labels:  analytics
V8 Analytics
v8 engine's cpu & heap-memory analytics
Stars: ✭ 181 (-5.24%)
Mutual labels:  analytics
Lares
R Library for Analytics and Machine Learning
Stars: ✭ 164 (-14.14%)
Mutual labels:  analytics
Jekyll Analytics
Plugin to easily add webanalytics to your jekyll site. Currently Google Analytics, Piwik and mPulse are supported.
Stars: ✭ 166 (-13.09%)
Mutual labels:  analytics
Alertmanager2es
Receives HTTP webhook notifications from AlertManager and inserts them into an Elasticsearch index for searching and analysis
Stars: ✭ 173 (-9.42%)
Mutual labels:  analytics
Goatcounter
Easy web analytics. No tracking of personal data.
Stars: ✭ 2,270 (+1088.48%)
Mutual labels:  analytics
Goaccess
GoAccess is a real-time web log analyzer and interactive viewer that runs in a terminal in *nix systems or through your browser.
Stars: ✭ 14,096 (+7280.1%)
Mutual labels:  analytics
Angulartics
Analytics for AngularJS applications.
Stars: ✭ 1,966 (+929.32%)
Mutual labels:  analytics
Aws Serverless Data Lake Framework
Enterprise-grade, production-hardened, serverless data lake on AWS
Stars: ✭ 179 (-6.28%)
Mutual labels:  analytics
Swiv
For the open source UI formerly know as Pivot
Stars: ✭ 165 (-13.61%)
Mutual labels:  analytics
Stacks Cli
📊 Analyze website stack from the terminal 💻
Stars: ✭ 1,962 (+927.23%)
Mutual labels:  analytics
Web Database Analytics
Web scrapping and related analytics using Python tools
Stars: ✭ 175 (-8.38%)
Mutual labels:  analytics
Stats
A well tested and comprehensive Golang statistics library package with no dependencies.
Stars: ✭ 2,196 (+1049.74%)
Mutual labels:  analytics
Mypaas
Run your own PaaS using Docker, Traefik, and great analytics
Stars: ✭ 183 (-4.19%)
Mutual labels:  analytics
Swiggy Analytics
Analyse your swiggy orders 🍔
Stars: ✭ 163 (-14.66%)
Mutual labels:  analytics
Amplify Cli
The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Stars: ✭ 2,399 (+1156.02%)
Mutual labels:  analytics
Gtm Module
Google Tag Manager Module for Nuxt.js
Stars: ✭ 187 (-2.09%)
Mutual labels:  analytics
Sparkliner
Sparkliner — easy way to make sparkline graph [Sketch plugin]
Stars: ✭ 184 (-3.66%)
Mutual labels:  analytics
Ios Consent Sdk
Configurable consent SDK for iOS
Stars: ✭ 178 (-6.81%)
Mutual labels:  analytics

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

Don't forget to enable OverloadedStrings:

:set -XOverloadedStrings

Now you're ready for dynamicness!

The Dynamic type

In the dynamic package there is one type: Dynamic!

What, you were expecting something more? Guffaw!

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!

Heterogenous lists are what life is about:

> toCsv [ 1, "Chris" ]
"1.0\r\nChris\r\n"

I can't handle it!!!

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]

Append things together

Like in JavaScript, we try to do our best to make something out of appending...

> "Wat" <> 1 <> "!" <> Null
"Wat1!"

Suspicious?

It's real! This code runs just fine:

silly a =
  if a > 0
     then toJsonFile "out.txt" "Hi"
     else toJsonFile "out.txt" (5 + "a")

That passes the dynamic typing test.

Mix and match your regular Haskell functions

Here's an exporation of my Monzo (bank account) data.

Load up the JSON output:

> monzo <- fromJsonFile "monzo.json"

Preview what's in it:

> take 100 $ show monzo
"{\n    \"transactions\": [\n        {\n            \"amount\": 10000,\n            \"dedupe_id\": \"com.monzo.f"
> toKeys monzo
["transactions"]

OK, just transactions. How many?

> length $ toList $ monzo!"transactions"
119

What keys do I get in each transaction?

> toKeys $ head $ toList $ monzo!"transactions"
["amount","dedupe_id","attachments","can_be_made_subscription","fees","created","category","settled","can_split_the_bill","can_add_to_tab","originator","currency","include_in_spending","merchant","can_be_excluded_from_breakdown","international","counterparty","scheme","local_currency","metadata","id","labels","updated","account_balance","is_load","account_id","notes","user_id","local_amount","description"]

What's in amount?

> (!"amount") $ head $ toList $ monzo!"transactions"
10000

Looks like pennies, let's divide that by 100. What's the total +/- sum of my last 5 transactions?

> sum $ map ((/100) . (!"amount")) $ take 5 $ toList $ monzo!"transactions"
468.65

What categories are there?

> nub $ map (!"category") $ toList $ monzo!"transactions"
["general","entertainment","groceries","eating_out","shopping","expenses","bills","personal_care","cash"]

How many transactions did I do in each category? Let's use Data.Map to histogram that.

> fromDict $ M.toList $ foldl (\cats cat -> M.insertWith (+) cat 1 cats) mempty $ map (!"category") $ toList $ monzo!"transactions"
{
    "personal_care": 2,
    "entertainment": 8,
    "bills": 3,
    "general": 58,
    "groceries": 16,
    "shopping": 8,
    "expenses": 19,
    "eating_out": 4,
    "cash": 1
}
>

Cool!

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].