packages feed

haskell-fsrs-7.0.0: src/FSRS/Types.hs

{-# LANGUAGE DerivingStrategies #-}

-- | The vocabulary shared by the whole package: the four grades a reviewer can
-- give a card, and the two-variable memory state FSRS tracks for it.
module FSRS.Types
  ( -- * Ratings
    Rating (..)
  , allRatings
  , ratingToInt
  , ratingFromInt

    -- * Memory state
  , MemoryState (..)

    -- * Type synonyms
  , Stability
  , Difficulty
  , Retrievability
  , Days
  ) where

-- | How well the card was recalled. The 'Enum' instance counts from @0@; the
-- FSRS papers and reference implementations number the ratings from @1@, which
-- is what 'ratingToInt' gives you.
data Rating
  = Again
  | Hard
  | Good
  | Easy
  deriving stock (Eq, Ord, Show, Read, Enum, Bounded)

-- | Every rating, from 'Again' to 'Easy'.
allRatings :: [Rating]
allRatings = [minBound .. maxBound]

-- | The rating as FSRS numbers it: @1@ for 'Again' through @4@ for 'Easy'.
ratingToInt :: Rating -> Int
ratingToInt r = fromEnum r + 1

-- | Inverse of 'ratingToInt'. 'Nothing' outside @1..4@.
ratingFromInt :: Int -> Maybe Rating
ratingFromInt n
  | n >= 1 && n <= 4 = Just (toEnum (n - 1))
  | otherwise = Nothing

-- | Memory half-life in days: the larger it is, the slower the card is
-- forgotten. In FSRS-7 stability is a genuine continuous quantity — sub-day
-- values are meaningful and are what the model uses for same-day reviews.
type Stability = Double

-- | How hard the card is for this reviewer, on a @[1, 10]@ scale.
type Difficulty = Double

-- | Probability of recall, in @(0, 1]@.
type Retrievability = Double

-- | A duration in days. Fractional values are meaningful throughout FSRS-7:
-- ten minutes is @10 / 1440@.
type Days = Double

-- | Everything FSRS remembers about a card.
data MemoryState = MemoryState
  { memoryStability :: !Stability
  , memoryDifficulty :: !Difficulty
  }
  deriving stock (Eq, Ord, Show, Read)