Contesto: Mi sto avvicinando a Haskell dal punto di vista della conversione degli errori di runtime in errori di compilazione. La mia ipotesi è che questo è possibile se si può codificare la logica di business all'interno dei tipi del programma stesso.Codifica presenza/assenza di autenticazione a livello di tipo
Sto scrivendo un bot di Telegram, che dovrebbe essere accessibile dagli utenti all'interno della mia azienda. Per ottenere questa "restrizione", ogni volta che qualcuno inizia a chattare con il bot, cerca in chat_id
una tabella e controlla se esiste uno oauth_token
valido. In caso contrario, all'utente verrà prima inviato un link per completare un OAuth di Google (l'e-mail della nostra azienda è ospitata su Google Apps for Business).
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
VLUser
email String
chatId Integer
tgramUserId Integer
tgramFirstName String
tgramLastName String Maybe
tgramUsername String Maybe
oauthToken String Maybe
deriving Show
|]
Gli utenti con una valida oauth_token
sarà in grado di dare il bot Telegram alcuni comandi, che gli utenti non autenticati non dovrebbero essere in grado di dare.
Ora, sto cercando di codificare questa logica a livello di tipo stesso. Ci saranno alcune funzioni nel mio codice Haskell che avranno la possibilità di accettare, come argomenti, entrambi gli utenti autentificati non autentificati, &; mentre alcune funzioni dovrebbero accettare solo utenti autenticati.
Se continuo a passare oggetti utente dello stesso tipo, vale a dire VLUser
ovunque, quindi dovrò fare attenzione a verificare la presenza di oauthToken
in ogni funzione. C'è un modo per creare due tipi di utente - VLUser
e VLUserAuthenticated
dove:
- Sia mappa per la stessa tabella sottostante
- Un
VLUserAuthenticated
può essere un'istanza solo se si ha unoauthToken
Questo sembra simile al problema di un mutex. Si desidera specificare a livello di testo se la funzione richiede il blocco o meno. Puoi vedere un possibile modo di affrontare questo [qui] (http://dev.stephendiehl.com/hask/#indexed-monads) per vedere il tipo 'IState'. Sostituisci 'Locked' e' Unlocked' con 'Authenticated' e' UnAuthenticated' e fornisci all'utente una funzione 'login' che controlla il token' oauth' e che è l'unico modo per ottenere un valore 'Authenticated'. – Bakuriu