fp-ts icon indicating copy to clipboard operation
fp-ts copied to clipboard

Case-insensitive string module

Open mlegenhausen opened this issue 4 years ago • 6 comments

First of all I would like to validate that my assumption is correct that the set of case-insensitive strings form a total oder? If that holds I would like to contribute a caseInsensitiveOrd (naming suggestions are welcome) instance.

mlegenhausen avatar Apr 08 '21 10:04 mlegenhausen

do you mean case-insensitive?

gkamperis avatar Apr 08 '21 12:04 gkamperis

Doh, fixed 😅

mlegenhausen avatar Apr 08 '21 12:04 mlegenhausen

@mlegenhausen what's the definition of compare?

gcanti avatar Apr 08 '21 15:04 gcanti

My naive approach would be the following definition:

import * as O from 'fp-ts/Ord'

declare const Ord: Ord<string>

export const ciOrd: Ord<string> = pipe(Ord, O.contramap(s => s.toLowerCase()))

mlegenhausen avatar Apr 09 '21 11:04 mlegenhausen

Found a haskell package that does even more than I currently thought of: https://hackage.haskell.org/package/case-insensitive-1.2.1.0/docs/Data-CaseInsensitive.html

Maybe the cleaned way would be add a caseInsensitiveString.ts module.

mlegenhausen avatar Apr 09 '21 11:04 mlegenhausen

Based on the ideas from the package I think it would be the cleanest way to use a branded type and copy the functionality from the string module.

import * as E from 'fp-ts/Eq'
import * as M from 'fp-ts/Monoid'
import * as O from 'fp-ts/Ord'
import * as S from 'fp-ts/Semigroup'
import * as Sh from 'fp-ts/Show'
import * as s from 'fp-ts/string'

export type CaseInsensitiveString = string & { readonly CaseInsensitiveString: unique symbol }

export const fromString = (s: string): CaseInsensitiveString => s.toLowerCase() as any

export const Eq: E.Eq<CaseInsensitiveString> = s.Eq

export const Semigroup: S.Semigroup<CaseInsensitiveString> = s.Semigroup as any

export const Monoid: M.Monoid<CaseInsensitiveString> = s.Monoid as any

export const Ord: O.Ord<CaseInsensitiveString> = s.Ord

export const Show: Sh.Show<CaseInsensitiveString> = s.Show

export const empty: CaseInsensitiveString = '' as any

export const isEmpty = (s: CaseInsensitiveString): boolean => s.length === 0

export const size = (s: CaseInsensitiveString): number => s.length

Don't know if this a to specific type for fp-ts?

mlegenhausen avatar Apr 09 '21 12:04 mlegenhausen