Skip to content

Instantly share code, notes, and snippets.

@kraftdorian
Last active November 14, 2021 21:23
Show Gist options
  • Save kraftdorian/448a5db38ef9ec160cb8f7b180578d37 to your computer and use it in GitHub Desktop.
Save kraftdorian/448a5db38ef9ec160cb8f7b180578d37 to your computer and use it in GitHub Desktop.
Some basic experiments in Haskell
-- http://learnyouahaskell.com/modules#making-our-own-modules
module User (
Account,
AccountRole,
accounts,
isAccountRoleEqual,
isAccountRoleSet,
filterAccountsWithRoleSet,
filterAccountsByRole,
filterAccountsByAdminRole
) where
import Data.Maybe (isNothing)
data AccountRole = User | Admin deriving (Show, Eq, Enum)
-- http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax
data Account = Account {
firstName :: String,
lastName :: String,
login :: String,
role :: Maybe AccountRole
} deriving (Show, Eq)
accounts :: [Account]
accounts = [Account {firstName = "Alice", lastName = "First", login = "afirst", role = Just Admin},
Account {firstName = "Bob", lastName = "Second", login = "bsecond", role = Just User},
Account {firstName = "Charlie", lastName = "Third", login = "cthird", role = Just User},
Account {firstName = "Dave", lastName = "Fourth", login = "dfourth", role = Nothing}]
isAccountRoleEqual :: Maybe AccountRole -> Account -> Bool
isAccountRoleEqual r a = role a == r
isAccountRoleSet :: Account -> Bool
isAccountRoleSet a =
let accountRole = role a
in not $ isNothing accountRole
filterAccountsWithRoleSet :: [Account] -> [Account]
filterAccountsWithRoleSet a = filter isAccountRoleSet a
filterAccountsByRole :: Maybe AccountRole -> [Account] -> [Account]
filterAccountsByRole r a = filter (isAccountRoleEqual r) a
-- This is an example of partially applied fn.
-- It inherits the declaration from filterAccountsByRole, excluding the first argument.
filterAccountsByAdminRole :: [Account] -> [Account]
filterAccountsByAdminRole = filterAccountsByRole $ Just Admin
// TypeScript implementation to reflect the Haskell code
enum AccountRole { User, Admin }
const { User, Admin } = AccountRole;
interface IAccount {
firstName: string;
lastName: string;
login: string;
role: AccountRole | undefined;
}
const accounts: Array<IAccount> = [
{ firstName: 'Alice', lastName: 'First', login: 'afirst', role: Admin },
{ firstName: 'Bob', lastName: 'Second', login: 'bsecond', role: User },
{ firstName: 'Charlie', lastName: 'Third', login: 'cthird', role: User },
{ firstName: 'Dave', lastName: 'Fourth', login: 'dfourth', role: undefined },
];
function isAccountRoleEqual(r: AccountRole): (a: IAccount) => boolean {
return (a) => (
a.role === r
);
}
function isAccountRoleSet(a: IAccount): boolean {
return a.role !== undefined;
}
function filterAccountsWithRoleSet(a: Array<IAccount>): Array<IAccount> {
return a.filter(isAccountRoleSet);
}
function filterAccountsByRole(r: AccountRole): (a: Array<IAccount>) => Array<IAccount> {
return (a) => (
a.filter(
isAccountRoleEqual(r)
)
);
}
function filterAccountsByAdminRole(a: Array<IAccount>): Array<IAccount> {
return filterAccountsByRole(Admin)(a);
}
export {
IAccount,
AccountRole,
accounts,
isAccountRoleEqual,
isAccountRoleSet,
filterAccountsWithRoleSet,
filterAccountsByRole,
filterAccountsByAdminRole
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment