{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RankNTypes #-}

{-|
Module      : Data.Radian
Copyright   : (C) CSIRO 2018
Copyright   : (C) Tony Morris 2020-2021
License     : BSD3
Maintainer  : Tony Morris <ʇǝu˙sıɹɹoɯʇ@ןןǝʞsɐɥ>
Stability   : experimental
Portability : portable

Isomorphisms between degrees and radians.
-}
module Data.Radian(
  toRadians
, fromRadians
) where

import Data.Functor(Functor(fmap))
import Data.Profunctor(Profunctor(dimap))
import Prelude(Num((*)), Fractional((/)), Floating, pi)

-- | An isomorphism between radians and degrees.
toRadians ::
  (Floating a, Floating b) =>
  Iso a b a b
toRadians :: Iso a b a b
toRadians =
  (a -> a) -> (f b -> f b) -> p a (f b) -> p a (f b)
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap
    a -> a
forall a. Floating a => a -> a
to
    ((b -> b) -> f b -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall a. Floating a => a -> a
fr)

-- | An isomorphism between degrees and radians.
fromRadians ::
  (Floating a, Floating b) =>
  Iso a b a b
fromRadians :: Iso a b a b
fromRadians =
  (a -> a) -> (f b -> f b) -> p a (f b) -> p a (f b)
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap
    a -> a
forall a. Floating a => a -> a
fr
    ((b -> b) -> f b -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> b
forall a. Floating a => a -> a
to)

----

to ::
  Floating a =>
  a
  -> a
to :: a -> a
to a
a =
  a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
forall a. Floating a => a
pi a -> a -> a
forall a. Num a => a -> a -> a
* a
180

fr ::
  Floating a =>
  a
  -> a
fr :: a -> a
fr a
a =
  a
a a -> a -> a
forall a. Fractional a => a -> a -> a
/ a
180 a -> a -> a
forall a. Num a => a -> a -> a
* a
forall a. Floating a => a
pi

type Iso s t a b =
  forall p f.
  (Profunctor p, Functor f) =>
  p a (f b) -> p s (f t)