Jaro similarity: Difference between revisions

m
(Realize in F#)
m (→‎Python :: Composition of pure functions: Tidied, updated primitives.)
Line 2,111:
import itertools
 
 
# --------------------- JARO FUNCTION ----------------------
 
# jaro :: String -> String -> Float
Line 2,116 ⟶ 2,118:
'''The Jaro distance between two strings.'''
def go(s1, s2):
m, t = fanArrowap(compose(Tuple, len)(transpositionSum)(
matches(s1, s2)transpositionSum
)(matches(s1, s2))
return 0 if 0 == m else (
(1 / 3) * ((m / len(s1)) + (m / len(s2)) + ((m - t) / m))
m / len(s2)
) + ((m - t) / m))
)
return lambda y: go(x, y)
 
 
# -------------------------- TEST --------------------------
# main :: IO ()
def main():
'''TestsSample word pairs'''
 
print(
tabulatedfTable('Jaro distances:\n')(str)(showPrecision(3))(
showPrecision(3)
)(
uncurry(jaro)
)([
Line 2,141 ⟶ 2,148:
 
 
# JARO HELPER FUNCTIONS ----------------- JARO HELPER FUNCTIONS ------------------
 
 
# transpositionSum :: [(Int, Char)] -> Int
Line 2,159 ⟶ 2,165:
 
[(_, xs), (l2, ys)] = sorted(map(
fanArrowap(compose(Tuple, len))(list), [s1, s2]
))
r = l2 // 2 - 1
Line 2,179 ⟶ 2,185:
 
 
# GENERIC FUNCTIONS ------------------- GENERIC FUNCTIONS --------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.'''
Wrapper containing the result of a computation.
)'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
Line 2,189 ⟶ 2,197:
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.'''
Empty wrapper returned where a computation is not possible.
)'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# composeTuple (<<<,) :: (ba -> c)b -> (a ->, b) -> a -> c
def composeTuple(gx):
'''Constructor for a pair of values,
'''Function composition.'''
possibly of two different types.
return lambda f: lambda x: g(f(x))
'''
def go(y):
return (
x + (y,)
) if isinstance(x, tuple) else (x, y)
return lambda xs: (go
 
 
# fanArrow (&&&)ap :: (a -> b -> c) -> (a -> cb) -> (a -> (b, c))
def fanArrowap(f):
'''Applicative instance for functions.
'''
def go(g):
def fxgx(x):
return f(x)(
g(x)
)
return fxgx
return go
 
 
# compose :: ((a -> a), ...) -> (a -> a)
def compose(*fs):
'''Composition, from right to left,
'''A tuple of thea outputsseries of two separate functions.
'''
def go(xShow, fxShow, f, xsg):
def fg(x):
return f(g(x))
return fg
return lambdareduce(go, f:fs, lambda x: g(f(x))
 
 
Line 2,202 ⟶ 2,243:
# drop :: Int -> String -> String
def drop(n):
'''The sublist of xs beginning at (zero-based) index n.'''
(zero-based) index n.
'''
def go(xs):
if isinstance(xs, (list, tuple, str)):
return xs[n:]
else:
take(n)(xs)
return xs
return lambda xs: go(xs)
 
 
Line 2,216 ⟶ 2,259:
'''Just the index of the first element in xs
which is equal to x,
or Nothing if there is no such element.'''
'''
def go(xs):
try:
Line 2,222 ⟶ 2,266:
except ValueError:
return Nothing()
return lambda xs: go(xs)
 
 
# fanArrow (&&&) :: (a -> b) -> (a -> c) -> (a -> (b, c))
def fanArrow(f):
'''A tuple of the outputs of two separate functions
applied to the same value.'''
return lambda g: lambda x: (f(x), g(x))
 
 
# fst :: (a, b) -> a
def fst(tpl):
'''First componentmember of a tuplepair.'''
return tpl[0]
 
Line 2,242 ⟶ 2,279:
'''Either the default value v, if m is Nothing,
or the application of f to x,
where the Maybe valuem is Just(x).'''
'''
return lambda f: lambda m: v if m.get('Nothing') else (
return lambda f: lambda f(m.get: v if ('Just'))
return lambda f: lambda None is m: v ifor m.get('Nothing') else (
)
) else f(m.get('Just'))
 
 
Line 2,255 ⟶ 2,293:
 
 
# tabulatedfTable :: String -> (a -> String) ->
# (b -> String) -> (a -> (b) -> String)[a] -> String
def tabulatedfTable(s):
# (a -> b) -> [a] -> String
def tabulated(s):
'''Heading -> x display function -> fx display function ->
f -> value listxs -> tabular string.'''
'''
def go(xShow, fxShow, f, xs):
def w = max(map(compose(len)gox(xShow), xs)):
returndef s + '\n' + '\n'.joingofx(fxShow):
xShow(x).rjust(w,def ' ') + ' -> ' + fxShowgof(f(x)) for x in xs:
def goxs(xs):
ys = [xShow(x) for x in xs]
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f w = max(map(len, xsys))
 
)
def arrowed(x, y):
return y.rjust(w, ' ') + (
# (a -> b) -> [a]' -> String' + fxShow(f(x))
)
return s + '\n' + '\n'.join(
map(arrowed, xs, ys)
)
return goxs
return gof
return gofx
return gox
 
 
Line 2,275 ⟶ 2,323:
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
'''
islice = itertools.islice
 
return lambda xs: (
def go(xs[0):n]
ifreturn isinstance(xs, list)
else list(islice(xs, xs[0:n))]
if isinstance(xs, (list, tuple))
)
else list(islice(xs, n))
)
return go
 
 
9,655

edits