initial commit
This commit is contained in:
commit
dd74a783aa
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.*.swp
|
||||||
|
/dist
|
30
LICENSE
Normal file
30
LICENSE
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
Copyright (c) 2015, Eric Mertens
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of Eric Mertens nor the names of other
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
slide-dsl.cabal
Normal file
23
slide-dsl.cabal
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
-- Initial slide-dsl.cabal generated by cabal init. For further
|
||||||
|
-- documentation, see http://haskell.org/cabal/users-guide/
|
||||||
|
|
||||||
|
name: slide-dsl
|
||||||
|
version: 0.1.0.0
|
||||||
|
-- synopsis:
|
||||||
|
-- description:
|
||||||
|
license: BSD3
|
||||||
|
license-file: LICENSE
|
||||||
|
author: Eric Mertens
|
||||||
|
maintainer: emertens@gmail.com
|
||||||
|
-- copyright:
|
||||||
|
category: Math
|
||||||
|
build-type: Simple
|
||||||
|
-- extra-source-files:
|
||||||
|
cabal-version: >=1.10
|
||||||
|
|
||||||
|
library
|
||||||
|
exposed-modules: SlideRule
|
||||||
|
other-extensions: GeneralizedNewtypeDeriving
|
||||||
|
build-depends: base >=4.7 && <4.8, transformers >=0.3 && <0.4
|
||||||
|
hs-source-dirs: src
|
||||||
|
default-language: Haskell2010
|
191
src/SlideRule.hs
Normal file
191
src/SlideRule.hs
Normal file
|
@ -0,0 +1,191 @@
|
||||||
|
{-# LANGUAGE KindSignatures #-}
|
||||||
|
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
module SlideRule where
|
||||||
|
|
||||||
|
import Control.Applicative
|
||||||
|
import Control.Monad.Trans.State
|
||||||
|
import Data.Fixed (mod')
|
||||||
|
import Numeric
|
||||||
|
|
||||||
|
newtype SlideRule a = SlideRule (State SlideState a)
|
||||||
|
deriving (Monad, Applicative, Functor)
|
||||||
|
|
||||||
|
data SlideState = SlideState
|
||||||
|
{ slideWheel :: Double
|
||||||
|
, slideCursor :: Double
|
||||||
|
}
|
||||||
|
|
||||||
|
initialState :: SlideState
|
||||||
|
initialState = SlideState
|
||||||
|
{ slideWheel = 0
|
||||||
|
, slideCursor = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
runSlideRule :: SlideRule a -> a
|
||||||
|
runSlideRule (SlideRule m) = evalState m initialState
|
||||||
|
|
||||||
|
printAnswer :: IsOnWheel pos => SlideRule (Scale pos) -> String
|
||||||
|
printAnswer s = showFFloat (Just 3) (runSlideRule (readCursor =<< s)) ""
|
||||||
|
|
||||||
|
instance Show a => Show (SlideRule a) where
|
||||||
|
show = show . runSlideRule
|
||||||
|
|
||||||
|
data ScalePosition = OnWheel | OffWheel
|
||||||
|
|
||||||
|
class IsOnWheel (pos :: ScalePosition) where
|
||||||
|
scaleWheel :: scale pos -> Bool
|
||||||
|
instance IsOnWheel OnWheel where scaleWheel _ = True
|
||||||
|
instance IsOnWheel OffWheel where scaleWheel _ = False
|
||||||
|
|
||||||
|
data Scale (w :: ScalePosition) = Scale
|
||||||
|
{ scaleName :: String
|
||||||
|
, scaleFun :: Double -> Double
|
||||||
|
, scaleFun' :: Double -> Double
|
||||||
|
}
|
||||||
|
|
||||||
|
cScale :: Scale OnWheel
|
||||||
|
cScale = Scale
|
||||||
|
{ scaleName = "C"
|
||||||
|
, scaleFun = logBase 10
|
||||||
|
, scaleFun' = (10**)
|
||||||
|
}
|
||||||
|
|
||||||
|
ciScale :: Scale OnWheel
|
||||||
|
ciScale = Scale
|
||||||
|
{ scaleName = "CI"
|
||||||
|
, scaleFun = \x -> mod' (1-logBase 10 x) 1
|
||||||
|
, scaleFun' = \x -> 10** mod' (1-x) 1
|
||||||
|
}
|
||||||
|
|
||||||
|
dScale :: Scale OffWheel
|
||||||
|
dScale = Scale
|
||||||
|
{ scaleName = "D"
|
||||||
|
, scaleFun = logBase 10
|
||||||
|
, scaleFun' = (10**)
|
||||||
|
}
|
||||||
|
|
||||||
|
aScale :: Scale OffWheel
|
||||||
|
aScale = Scale
|
||||||
|
{ scaleName = "A"
|
||||||
|
, scaleFun = logBase 100
|
||||||
|
, scaleFun' = (100**)
|
||||||
|
}
|
||||||
|
|
||||||
|
bScale :: Scale OnWheel
|
||||||
|
bScale = Scale
|
||||||
|
{ scaleName = "B"
|
||||||
|
, scaleFun = logBase 100
|
||||||
|
, scaleFun' = (100**)
|
||||||
|
}
|
||||||
|
|
||||||
|
kScale :: Scale OffWheel
|
||||||
|
kScale = Scale
|
||||||
|
{ scaleName = "K"
|
||||||
|
, scaleFun = logBase 1000
|
||||||
|
, scaleFun' = (1000**)
|
||||||
|
}
|
||||||
|
|
||||||
|
llScale :: Int -> Scale pos
|
||||||
|
llScale n = Scale
|
||||||
|
{ scaleName = "LL" ++ show n
|
||||||
|
, scaleFun = subtract off . logBase 10 . log
|
||||||
|
, scaleFun' = exp . (10**) . (+off)
|
||||||
|
}
|
||||||
|
where
|
||||||
|
off = fromIntegral n - 3
|
||||||
|
|
||||||
|
ll3Scale :: Scale OffWheel
|
||||||
|
ll3Scale = llScale 3
|
||||||
|
|
||||||
|
ll2Scale :: Scale OffWheel
|
||||||
|
ll2Scale = llScale 2
|
||||||
|
|
||||||
|
sScale :: Scale OnWheel
|
||||||
|
sScale = Scale
|
||||||
|
{ scaleName = "S"
|
||||||
|
, scaleFun = (+1) . logBase 10 . sin . degToRad
|
||||||
|
, scaleFun' = radToDeg . asin . (10**) . subtract 1
|
||||||
|
}
|
||||||
|
|
||||||
|
stScale :: Scale OnWheel
|
||||||
|
stScale = Scale
|
||||||
|
{ scaleName = "ST"
|
||||||
|
, scaleFun = (+2) . logBase 10 . sin . degToRad
|
||||||
|
, scaleFun' = radToDeg . asin . (10**) . subtract 2
|
||||||
|
}
|
||||||
|
|
||||||
|
t1Scale :: Scale OnWheel
|
||||||
|
t1Scale = Scale
|
||||||
|
{ scaleName = "T1"
|
||||||
|
, scaleFun = (+1) . logBase 10 . tan . degToRad
|
||||||
|
, scaleFun' = radToDeg . atan . (10**) . subtract 1
|
||||||
|
}
|
||||||
|
|
||||||
|
t2Scale :: Scale OnWheel
|
||||||
|
t2Scale = Scale
|
||||||
|
{ scaleName = "T2"
|
||||||
|
, scaleFun = logBase 10 . tan . degToRad
|
||||||
|
, scaleFun' = radToDeg . atan . (10**)
|
||||||
|
}
|
||||||
|
|
||||||
|
degToRad :: Double -> Double
|
||||||
|
degToRad x = x * pi / 180
|
||||||
|
|
||||||
|
radToDeg :: Double -> Double
|
||||||
|
radToDeg x = x * 180 / pi
|
||||||
|
|
||||||
|
getCursorPos :: SlideRule Double
|
||||||
|
getCursorPos = SlideRule (gets slideCursor)
|
||||||
|
|
||||||
|
getWheelPos :: SlideRule Double
|
||||||
|
getWheelPos = SlideRule (gets slideWheel)
|
||||||
|
|
||||||
|
setCursorPos :: Double -> SlideRule ()
|
||||||
|
setCursorPos x = SlideRule (modify (\s -> s { slideCursor = x }))
|
||||||
|
|
||||||
|
setWheelPos :: Double -> SlideRule ()
|
||||||
|
setWheelPos x = SlideRule (modify (\s -> s { slideWheel = x }))
|
||||||
|
|
||||||
|
mark :: IsOnWheel pos => Scale pos -> Double -> SlideRule ()
|
||||||
|
mark scale value
|
||||||
|
|
||||||
|
| scaleWheel scale = do w <- getWheelPos
|
||||||
|
setCursorPos (mod' (w+frac) 1)
|
||||||
|
|
||||||
|
| otherwise = do setCursorPos frac
|
||||||
|
where
|
||||||
|
frac = scaleFun scale value
|
||||||
|
|
||||||
|
readCursor :: IsOnWheel pos => Scale pos -> SlideRule Double
|
||||||
|
readCursor scale = do
|
||||||
|
c <- getCursorPos
|
||||||
|
w <- if scaleWheel scale then getWheelPos else return 0
|
||||||
|
let c' = mod' (c-w) 1
|
||||||
|
return (scaleFun' scale c')
|
||||||
|
|
||||||
|
move :: Scale OnWheel -> Double -> SlideRule ()
|
||||||
|
move scale value =
|
||||||
|
do c <- getCursorPos
|
||||||
|
let v = scaleFun scale value
|
||||||
|
setWheelPos (mod' (c - v) 1)
|
||||||
|
|
||||||
|
multiply :: Double -> Double -> String
|
||||||
|
multiply x y = printAnswer $
|
||||||
|
do mark dScale x
|
||||||
|
move ciScale y
|
||||||
|
mark ciScale 1
|
||||||
|
return dScale
|
||||||
|
|
||||||
|
fourthPowCIK :: Double -> String
|
||||||
|
fourthPowCIK x = printAnswer $
|
||||||
|
do mark kScale x
|
||||||
|
move ciScale x
|
||||||
|
mark ciScale 1
|
||||||
|
return kScale
|
||||||
|
|
||||||
|
fourthPowCCIA :: Double -> String
|
||||||
|
fourthPowCCIA x = printAnswer $
|
||||||
|
do move ciScale x
|
||||||
|
mark cScale x
|
||||||
|
return aScale
|
Loading…
Reference in New Issue
Block a user