cast: Abstact cast pattern

[ bsd3, library, pattern ] [ Propose Tags ] [ Report a vulnerability ]

Generalized pattern that allow cast one type for another. Look at README for example.


[Skip to Readme]

Modules

[Index]

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.1.0.0, 0.1.0.1, 0.1.0.2
Dependencies base (>=4.7 && <5) [details]
License BSD-3-Clause
Copyright Copyright: (c) 2016 Bogdan Neterebskii
Author Bogdan Neterebskii
Maintainer bog2dan1@gmail.com
Category Pattern
Home page https://github.com/haskell-patterns/cast#readme
Source repo head: git clone https://github.com/haskell-patterns/cast
Uploaded by ozzzzz at 2017-07-31T09:19:10Z
Distributions LTSHaskell:0.1.0.2, NixOS:0.1.0.2, Stackage:0.1.0.2
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 2711 total (17 in the last 30 days)
Rating 2.0 (votes: 1) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2017-07-31 [all 1 reports]

Readme for cast-0.1.0.2

[back to package description]

Haskell pattern: cast

This pattern allows to incapsulate convert from one type of object for another.

Example

Suppose you want convert different speed units to meter per second:

{-# LANGUAGE MultiParamTypeClasses #-}

import Pattern.Cast

newtype MeterPerSecond   = MeterPerSecond Float
  deriving (Ord, Eq)
newtype KilometerPerHour = KilometerPerHour Float
newtype MilesPerHour     = MilesPerHour Float

instance Cast KilometerPerHour MeterPerSecond where
  cast (KilometerPerHour v) = MeterPerSecond (0.277778 * v)

instance Cast MilesPerHour MeterPerSecond where
  cast (MilesPerHour v) = MeterPerSecond (0.44704 * v)

As you see, you have to use MultiParamTypeClasses language extension.

Then in every place you can just call one function cast:

> cast (KilometerPerHour 100) :: MeterPerSecond
MeterPerSecond 27.7778
> cast (MilesPerHour 100) :: MeterPerSecond
MeterPerSecond 44.704

You can type your functions more abstractly. Let's look at this synthetic example:

type Second = Float
type Meter  = Float

data Aircraft = Aircraft { distance :: Meter
                         , time     :: Second
                         }

instance Cast Aircraft MeterPerSecond where
  cast (Aircraft d t) = MeterPerSecond (d / t)

Then you can use Cast in type of your fuction like this (FlexibleContexts extension has to be used):

{-# LANGUAGE FlexibleContexts #-}

slowerThenSound :: Cast a MeterPerSecond => a -> Bool
slowerThenSound x = cast x < MeterPerSecond 340.29

And this fuction can be used with every type that can be converted in MeterPerSecond:

> slowerThenSound $ MeterPerSecond 200
True
> slowerThenSound $ KilometerPerHour 1000
True
> slowerThenSound $ Aircraft 1200 3
False