lue-bird/elm-keysset/5.0.2

Map

Map content inside a nested structure

type alias Mapping unmapped mapTag mapped =
Typed Checked mapTag Public (unmapped -> mapped)

Typed change

To create, combine

  • a tag that uniquely describes the part
  • a function that changes the unmapped to mapped
-- module Game exposing (Score, score)

type alias Game =
    { ..., score : Int }

type Score
    = Score

score : Mapping Game Score Int
score =
    Map.tag Score .score

To "nest" Mappings typed-value has some powerful helpers:

-- module String.Map exposing (each, Each, ToList, toList)
type ToList
    = ToList


toList : Mapping String ToList (List Char)
toList =
    Map.tag ToList String.toList


type Each
    = Each


each :
    Mapping element elementMapTag elementMapped
    -> Mapping (List element) ( Each, elementMapTag ) (List elementMapped)
each elementMapping =
    Typed.mapToWrap Each List.map elementMapping

There's nothing more to it

Use [Alter] if unmapped and mapped types are the same

type alias Altering subject alterTag =
Mapping subject alterTag subject

Mapping that will preserve the element type.

Altering can be used to simplify argument and result types

-- module User.Map exposing (onHead)


import Map


type alias User =
    { name : String, ... }


type Name
    = Name


name : Altering String nameAlterTag -> Altering User ( Name, nameAlterTag )
name =
    Typed.mapToWrap Name (\f user -> { user | name = user.name |> f })

This applies to records, types without any type variables or mapping some of many equal-typed elements

create

tag : tag -> (a -> b) -> Mapping a tag b

Create a uniquely tagged Mapping for a given function a -> b.

identity : Altering subject_ Identity

Returns what comes in without changing anything

"please edit"
    |> Map.with Map.identity
--> "please edit"

Opaque tag for identity

combine

Mapping mapped nextMapTag nextMapped
-> Mapping unmapped structureTag mapped
-> Mapping unmapped (Over structureTag nextMapTag) nextMapped

Transform elements as shown in a given Mapping with a given function

import Typed


type Book
    = Book


book : Mapping { book : { sales : Int } } Book { sales : Int }
book =
    Typed.tag Book .book


type Sales
    = Sales


sales : Mapping { sales : Int } Sales Int
sales =
    Typed.tag Sales .sales


{ book = { sales = 0 } }
    |> Map.with (book |> Map.over sales)
--> 0
type alias Over mapTag nextMapTag =
( OverTag, ( mapTag, nextMapTag ) )

Tag for over

type OverTag

Wrapper tag in Over

transform

with : Mapping unmapped mapTag_ mapped -> unmapped -> mapped

Apply the given change

import Typed


[ 'h', 'i' ]
    |> Map.with (Typed.tag { whatever = () } String.fromList)
--> "hi"