git @ Cat's Eye Technologies Dipple / master haskell / MapEmbedMaybe.hs
master

Tree @master (Download .tar.gz)

MapEmbedMaybe.hs @masterraw · history · blame

module MapEmbedMaybe where

-- SPDX-FileCopyrightText: Chris Pressey, the original author of this work, has dedicated it to the public domain.
-- For more information, please refer to <https://unlicense.org/>
-- SPDX-License-Identifier: Unlicense

-- I needed a general "mapEmbedMaybe" function (below) for something I was doing.
-- This source just shows how I derived it from more concrete examples.

-- First, a simple function for tests:
-- Given a list of pairs, show those pairs that are not equal.
-- Anything other than an empty lists returns indicates a mistake.

expect [] = []
expect ((a, b):rest) = if a == b then expect rest else ((a, b):expect rest)


-- Given a list of integers, return a list of lists of integers
-- where each list has one of the elements replaced by 0.

mapEmbedInts list =
    mapEmbedInts' list []
    where
        mapEmbedInts' [] prev = []
        mapEmbedInts' (x:xs) prev =
            [prev ++ [0] ++ xs] ++ mapEmbedInts' xs (prev ++ [x])

testMapEmbedInts = expect
  [
    (mapEmbedInts [1, 2, 3], [[0,2,3], [1,0,3], [1,2,0]])
  ]


-- Given a list of a's and an a, return a list of lists of a's
-- where each list has one of the a's replaced by the given a.

mapEmbedRepl list a =
    mapEmbedRepl' list a []
    where
        mapEmbedRepl' [] a prev = []
        mapEmbedRepl' (x:xs) a prev =
            [prev ++ [a] ++ xs] ++ mapEmbedRepl' xs a (prev ++ [x])

testMapEmbedRepl = expect
  [
    (mapEmbedRepl "abc" 'z', ["zbc", "azc", "abz"])
  ]


-- Given a list of a's and a function f from a to a, return a list of lists of a's
-- where each list has one of the a's replaced by the result of applying f to it.

mapEmbed list f =
    mapEmbed' list f []
    where
        mapEmbed' [] f prev = []
        mapEmbed' (x:xs) f prev =
            [prev ++ [f x] ++ xs] ++ mapEmbed' xs f (prev ++ [x])

testMapEmbed = expect
  [
    (mapEmbed [1, 2, 3] (\x -> x + 200), [[201,2,3],[1,202,3],[1,2,203]])
  ]


-- Like mapEmbed, except that f can fail (f maps a to Maybe a), and the lists
-- are only included in the result when f has succeeded.

mapEmbedMaybe list f =
    mapEmbedMaybe' list f []
    where
        mapEmbedMaybe' [] f prev = []
        mapEmbedMaybe' (x:xs) f prev =
            case f x of
                Just y  -> [prev ++ [y] ++ xs] ++ mapEmbedMaybe' xs f (prev ++ [x])
                Nothing -> mapEmbedMaybe' xs f (prev ++ [x])

testMapEmbedMaybe = expect
  [
    (mapEmbedMaybe [1, 2, 3, 4, 5] flt, [[1,2,3,99,5]])
  ]
  where flt 4 = Just 99
        flt _ = Nothing