Skip to content

Commit

Permalink
Avoid using partial functions from Data.List
Browse files Browse the repository at this point in the history
Use Data.List.Infinite, Data.List.NonEmpty and drop instead
  • Loading branch information
neilmayhew committed Mar 15, 2024
1 parent d7b78ef commit 2ab2c57
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 18 deletions.
11 changes: 7 additions & 4 deletions Analysis.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
module Analysis where

import Prelude hiding (head, iterate)

import Data.List.Infinite (Infinite ((:<)), head, iterate)

data Criticality = Maximum | Minimum | Inflection
deriving (Eq, Show, Read)

Expand Down Expand Up @@ -27,10 +31,9 @@ solve :: (Fractional t, Ord t) =>
solve f f' e (x0, _) = head . convergedBy e . iterate step $ x0
where step x = x - f x / f' x

dropWhile2 :: (t -> t -> Bool) -> [t] -> [t]
dropWhile2 p xs@(x : xs'@(x' : _)) = if not (p x x') then xs else dropWhile2 p xs'
dropWhile2 _ xs = xs
dropWhile2 :: (t -> t -> Bool) -> Infinite t -> Infinite t
dropWhile2 p xs@(x :< xs'@(x' :< _)) = if not (p x x') then xs else dropWhile2 p xs'

convergedBy :: (Num t, Ord t) => t -> [t] -> [t]
convergedBy :: (Num t, Ord t) => t -> Infinite t -> Infinite t
convergedBy e = dropWhile2 unconverging
where unconverging x x' = abs (x - x') >= e
2 changes: 1 addition & 1 deletion Extremes.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ main = do

let (highs, lows) = partition ((== Maximum) . exType) times
cmp = comparing (snd . exPoint)
ranges = zipWith sub times $ tail times
ranges = zipWith sub times $ drop 1 times
sub (Extremum (t, h) c) (Extremum (_, h') _) = Extremum (t, abs (h - h')) c

forM_ (take 10 $ sortBy (flip cmp) highs) $
Expand Down
4 changes: 4 additions & 0 deletions Tides.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ executable Tides
base >=4.6.0.1 && <5,
directory >=1.2.0.1 && <1.4,
filepath >=1.3.0.1 && <1.5,
infinite-list >=0.1 && <0.2,
mtl >=2.2.2 && <2.4,
time >=1.5 && <1.13,
time-locale-compat >=0.1.1.3 && <0.2,
Expand All @@ -64,6 +65,7 @@ executable Extremes
base >=4.6.0.1 && <5,
directory >=1.2.0.1 && <1.4,
filepath >=1.3.0.1 && <1.5,
infinite-list >=0.1 && <0.2,
time >=1.5 && <1.13,
time-locale-compat >=0.1.1.3 && <0.2,
tz >=0.0.0.5 && <0.2,
Expand Down Expand Up @@ -120,6 +122,7 @@ executable TestTides
base >=4.6.0.1 && <5,
directory >=1.2.0.1 && <1.4,
filepath >=1.3.0.1 && <1.5,
infinite-list >=0.1 && <0.2,
time >=1.5 && <1.13,
time-locale-compat >=0.1.1.3 && <0.2,
tz >=0.0.0.5 && <0.2,
Expand Down Expand Up @@ -213,6 +216,7 @@ test-suite TestRegressions
filepath >=1.3.0.1 && <1.5,
hspec >=2.7.6,
hspec-golden >=0.1.0.3,
infinite-list >=0.1 && <0.2,
mtl >=2.2.2 && <2.4,
process >=1.2.3 && <1.7,
random >=1.1 && <1.3,
Expand Down
21 changes: 11 additions & 10 deletions Tides.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import Control.Arrow (first)
import Control.Monad (unless, (<=<))
import Control.Monad.IO.Class (MonadIO(..))
import Data.Function
import Data.List (groupBy)
import Data.Time
import Data.Time.Zones

import qualified Data.List.NonEmpty as NE

type Prediction = (ZonedTime, Double)
type Event = Extremum Prediction

Expand All @@ -36,17 +37,17 @@ tides station begin end step = do

--name <- return . tshName . trHeader $ r
--country <- getCountry . trCountry $ r
tz <- liftIO . loadSystemTZ . tail <=< getTZFile . tshTZFile . trHeader $ r
tz <- liftIO . loadSystemTZ . dropWhile (== ':') <=< getTZFile . tshTZFile . trHeader $ r
units <- getLevelUnits . trLevelUnits $ r

let beginUTC = localTimeToUTCTZ' tz begin
endUTC = localTimeToUTCTZ' tz end
nextUTC = step `addUTCTime` beginUTC
years = groupBy ((==) `on` yot) [beginUTC, nextUTC .. endUTC]
years = NE.groupBy ((==) `on` yot) [beginUTC, nextUTC .. endUTC]
yot = yearOfTime :: UTCTime -> Int

let tides' times = do
let startYear = yearOfTime $ head times
let startYear = yearOfTime $ NE.head times
yearNum = fromIntegral startYear - baseYear

nodeFactors <- mapM (`getNodeFactor` yearNum) indices
Expand All @@ -62,19 +63,19 @@ tides station begin end step = do
tide = evaluate series
tide' = evaluate series'

heights = map (tide . toHours . timeOfTheYear) times
ztimes = map (toZonedTime tz) times
heights = NE.map (tide . toHours . timeOfTheYear) times
ztimes = NE.map (toZonedTime tz) times

beginHour = toHours . timeOfTheYear $ head times
endHour = toHours . timeOfTheYear $ last times
beginHour = toHours . timeOfTheYear $ NE.head times
endHour = toHours . timeOfTheYear $ NE.last times
hours = takeWhile (< endHour) [beginHour ..] ++ [endHour]
slots = zip hours (drop 1 hours)
reversals = filter (\(t0, t1) -> tide' t0 * tide' t1 <= 0) slots
events = concatMap findEvents reversals
findEvents = map toTideEvent . extrema series (1/240) -- 15s
toTideEvent = fmap . first $ toZonedTime tz . yhTimeToUtcTime . YHTime startYear

return (zip ztimes heights, events)
return (NE.zip ztimes heights, events)

where
d2r d = d * (pi / 180)
Expand All @@ -84,7 +85,7 @@ tides station begin end step = do

predictions <- mapM tides' years

return (concatMap fst predictions, concatMap snd predictions, units, tz)
return (concatMap (NE.toList . fst) predictions, concatMap snd predictions, units, tz)

-- Prefer the earlier time to the later time when LT is ambiguous
-- This matches the behaviour of xtide
Expand Down
7 changes: 4 additions & 3 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# vim: et:sw=2:sts=2

{ stdenv, lib, callPackage, mkDerivation, harmonicsType ? "free"
, base, base-compat, containers, directory, filepath, hspec, hspec-golden, mtl, process, QuickCheck, random, time, time-locale-compat, tz
, base, base-compat, containers, directory, filepath, hspec, hspec-golden
, infinite-list, mtl, process, QuickCheck, random, time, time-locale-compat, tz
, pkgs
}:

Expand All @@ -19,8 +20,8 @@ in
libraryHaskellDepends = [ base directory filepath ];
librarySystemDepends = [ tcd ];
executableHaskellDepends = [
base containers directory filepath mtl process QuickCheck random
time time-locale-compat tz ];
base containers directory filepath infinite-list mtl process QuickCheck
random time time-locale-compat tz ];
executableSystemDepends = [ tcd ];
testHaskellDepends = [
base base-compat directory filepath hspec hspec-golden mtl process
Expand Down

0 comments on commit 2ab2c57

Please sign in to comment.