Skip to content

Instantly share code, notes, and snippets.

@amalloy
Created September 27, 2016 20:30
Show Gist options
  • Save amalloy/18a89b3ed678ba6a8291eaa7e21d4ab2 to your computer and use it in GitHub Desktop.
Save amalloy/18a89b3ed678ba6a8291eaa7e21d4ab2 to your computer and use it in GitHub Desktop.
import Control.Monad
xs = Right 5
ys = Left "oops"
-- listComp = [(x, y) | x <- xs, y <- ys]
-- monad = do
-- x <- xs
-- y <- ys
-- return (x, y)
-- concats = concatMap (\x -> (concatMap (\y -> [(x, y)]) ys)) xs
binds = xs >>=
(\x -> ys >>=
(\y -> return (x, y)))
mystery xs = filterM (\_ -> [True, False]) xs
module Lev
( lev
) where
import Control.Monad.Trans.State
import Control.Monad
import Data.Array
type Lookup = Array (Int,Int) Int
type Input = Array Int Char
initState :: Int -> Int -> Lookup
initState m n = array ((0,0), (m,n)) $
[((i,0),i) | i <- [0..m]] ++
[((0,j),j) | j <- [0..n]]
-- algorithm from https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_full_matrix
lev' :: Input -> Input -> State Lookup Int
lev' s t = do
let (1,m) = bounds s
(1,n) = bounds t
forM_ [1..n] $ \j -> do
forM_ [1..m] $ \i -> do
d <- get
let substCost = if (s ! i) == (t ! j) then 0 else 1
choices = [ 1 + d ! (i-1,j),
1 + d ! ( i,j-1),
substCost + d ! (i-1,j-1)]
modify (// [((i,j), minimum choices)])
gets (! (m,n))
lev :: String -> String -> Int
lev s "" = length s
lev "" t = length t
lev s t = let m = length s
n = length t
in evalState (lev' (listArray (1,m) s) (listArray (1,n) t)) $ initState m n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment