I have some code doing explicit recursion, and on top of that it calls the same function twice when it doesn’t need to. I figure I can fix the latter, but need help with the former.
yesodIdentifier :: Text -> [LDAPEntry] -> Text
yesodIdentifier name ((LDAPEntry _ attributes):_) =
let (Just eMail) = L.lookup "proxyAddresses" attributes
partedEmail = L.map (S.splitOn "@") eMail -- now we have
-- [["garbage:name","domain"]]
in yesodIdentifier' name partedEmail -- the secondary function is the problem
where yesodIdentifier' :: Text -> [[String]] -> Text
yesodIdentifier' nameToMatch ((name:[domain]):rest) =
if ((unpack nameToMatch) == (sanitized name))
then (pack (sanitized name)) `append`
(pack "@") `append`
(pack domain)
else yesodIdentifier' nameToMatch rest
where sanitized :: String -> String
sanitized dirty =
let (garbage:[cleanedName]) = S.splitOn ":" dirty
in cleanedName
yesodIdentifier' name _ = pack "empty identifier"
What I am trying to do, is take the (String,[String]) from the LDAPEntry, and reduce it to the email address that matches the name given.
You can see where the recursion is. If I can fix this, I wouldn’t have to worry about yesodIdentifier' name _ = pack "empty identifier" as this code simply wouldn’t be called in the case that the user wasn’t in the LDAP database. I just put it there for completion.
I think this is better expressed as a fold, but I can’t quite express it correctly in my head. Any ideas?
This can be expressed as a filter. It’s not a fold since, if you do recurse, you’re recursing on rest and throwing away the earlier entries. You still have to handle the empty list:
yesodI nameToMatch list = let result = filter (match(unpack nameToMatch)) list match s1 (s2:[domain]) = s1 == s2 in case result of [] -> "empty identifier" res -> repack (head res) repack arg@(name:[domain]) = (pack (sanitized name)) `append` (pack "@") `append` (pack domain)