Lol, yeah. Sorry. Wasn't sure the best way to ask.
/home/disco/Documents/code/haskell/servant-auth-playground/src/Authorization.hs:81:20: error:
• Could not deduce (IsAuthorized a1 user)
arising from a use of ‘isAuthorized’
from the context: (IsAuthorizedConstraints claims user,
GetCombineLogic cl, GetMaybe (Head claims))
bound by the type signature for:
isAuthorized' :: forall k (claims :: [*]) user (cl :: CombineLogic) (a :: k).
(IsAuthorizedConstraints claims user, GetCombineLogic cl,
GetMaybe (Head claims)) =>
Proxy (Authorize' cl claims user) -> user -> Bool
at src/Authorization.hs:(68,1)-(76,9)
or from: Head claims ~ 'Just a1
bound by a pattern with constructor:
SJust :: forall a1 (a2 :: a1). Proxy a2 -> SMaybe ('Just a2),
in a case alternative
at src/Authorization.hs:81:5-15
• In the first argument of ‘combine’, namely
‘isAuthorized claim user’
In the expression:
isAuthorized claim user `combine` isAuthorized' nextClaims user
In a case alternative:
SJust claim
-> isAuthorized claim user `combine` isAuthorized' nextClaims user
where
nextClaims = Proxy @(Authorize' cl (Tail claims) user)
|
81 | SJust claim -> isAuthorized claim user `combine` isAuthorized' nextClaims user
| ^^^^^^^^^^^^^^^^^^^^^^^
/home/disco/Documents/code/haskell/servant-auth-playground/src/Authorization.hs:81:54: error:
• Could not deduce: IsAuthorizedConstraints (Tail claims) user
arising from a use of ‘isAuthorized'’
from the context: (IsAuthorizedConstraints claims user,
GetCombineLogic cl, GetMaybe (Head claims))
bound by the type signature for:
isAuthorized' :: forall k (claims :: [*]) user (cl :: CombineLogic) (a :: k).
(IsAuthorizedConstraints claims user, GetCombineLogic cl,
GetMaybe (Head claims)) =>
Proxy (Authorize' cl claims user) -> user -> Bool
at src/Authorization.hs:(68,1)-(76,9)
or from: Head claims ~ 'Just a1
bound by a pattern with constructor:
SJust :: forall a1 (a2 :: a1). Proxy a2 -> SMaybe ('Just a2),
in a case alternative
at src/Authorization.hs:81:5-15
• In the second argument of ‘combine’, namely
‘isAuthorized' nextClaims user’
In the expression:
isAuthorized claim user `combine` isAuthorized' nextClaims user
In a case alternative:
SJust claim
-> isAuthorized claim user `combine` isAuthorized' nextClaims user
where
nextClaims = Proxy @(Authorize' cl (Tail claims) user)
• Relevant bindings include
nextClaims :: Proxy (Authorize' cl (Tail claims) user)
(bound at src/Authorization.hs:82:13)
user :: user (bound at src/Authorization.hs:77:17)
isAuthorized' :: Proxy (Authorize' cl claims user) -> user -> Bool
(bound at src/Authorization.hs:77:1)
|
81 | SJust claim -> isAuthorized claim user `combine` isAuthorized' nextClaims user
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/disco/Documents/code/haskell/servant-auth-playground/src/Authorization.hs:81:54: error:
• Could not deduce (GetMaybe (Head (Tail claims)))
arising from a use of ‘isAuthorized'’
from the context: (IsAuthorizedConstraints claims user,
GetCombineLogic cl, GetMaybe (Head claims))
bound by the type signature for:
isAuthorized' :: forall k (claims :: [*]) user (cl :: CombineLogic) (a :: k).
(IsAuthorizedConstraints claims user, GetCombineLogic cl,
GetMaybe (Head claims)) =>
Proxy (Authorize' cl claims user) -> user -> Bool
at src/Authorization.hs:(68,1)-(76,9)
or from: Head claims ~ 'Just a1
bound by a pattern with constructor:
SJust :: forall a1 (a2 :: a1). Proxy a2 -> SMaybe ('Just a2),
in a case alternative
at src/Authorization.hs:81:5-15
• In the second argument of ‘combine’, namely
‘isAuthorized' nextClaims user’
In the expression:
isAuthorized claim user `combine` isAuthorized' nextClaims user
In a case alternative:
SJust claim
-> isAuthorized claim user `combine` isAuthorized' nextClaims user
where
nextClaims = Proxy @(Authorize' cl (Tail claims) user)
|
81 | SJust claim -> isAuthorized claim user `combine` isAuthorized' nextClaims user
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Instead of a GetMaybe class, start by passing the GADT explicitly. And instead of SMaybe, which will only give you one element Head claims, you need a type witness for the whole list claims.
moduleAuthorization(IsAuthorized(..),Authorize,AuthorizeAll,AuthorizeAny)whereimportData.Kind(Type)importData.Proxy(Proxy(..))classIsAuthorizedclaimuserwhereisAuthorized::Proxyclaim->user->BoolinstanceIsAuthorizedMany(Authorize'clclaimsuser)user=>IsAuthorized(Authorize'clclaimsuser)userwhereisAuthorized=isAuthorizedManydataCombineLogic=And|OrdataAuthorize'(combineLogic::CombineLogic)(claims::[Type])(user::Type)typeAuthorize(claim::Type)(user::Type)=Authorize''And'[claim]usertypeAuthorizeAll(claims::[Type])(user::Type)=Authorize''AndclaimsusertypeAuthorizeAny(claims::[Type])(user::Type)=Authorize''OrclaimsuserclassIsAuthorizedManyclaimsuserwhereisAuthorizedMany::Proxyclaims->user->BoolinstanceIsAuthorizedMany(Authorize''And'[]_user)_userwhereisAuthorizedMany__=Trueinstance(IsAuthorizedclaimuser,IsAuthorizedMany(Authorize''Andclaimsuser)user)=>IsAuthorizedMany(Authorize''And(claim': claims) user) user whereisAuthorizedMany_user=isAuthorized(Proxy@claim)user&&isAuthorizedMany(Proxy@(Authorize''Andclaimsuser))userinstanceIsAuthorizedMany(Authorize''Or'[]_user)_userwhereisAuthorizedMany__=Falseinstance(IsAuthorizedclaimuser,IsAuthorizedMany(Authorize''Orclaimsuser)user)=>IsAuthorizedMany(Authorize''Or(claim': claims) user) user whereisAuthorizedMany_user=isAuthorized(Proxy@claim)user||isAuthorizedMany(Proxy@(Authorize''Orclaimsuser))user
Is there anyway to get the isAuthorized' function to work?
What is the error message? That's a pretty big piece of code for one to assimilate without context.
Lol, yeah. Sorry. Wasn't sure the best way to ask.
From
Head claims = 'Just claim
GHC won't infer thatclaims = claim ': _
Instead of a
GetMaybe
class, start by passing the GADT explicitly. And instead ofSMaybe
, which will only give you one elementHead claims
, you need a type witness for the whole listclaims
.What about this? I think this is simpler.
Also Zulip's haskell highlighting is confused XD
And this seems to magically work. At least with this simple example.
(I just made a PR to pygments to fix it)
Oh wow that's awesome :D
The only weird part about this is that AuthorizeAny with an empty list is False and AuthorizeAll with an empty list is True
Weird but monoidal.
The intention is to use this as a servant combinator. So I think I could just write my HasServer instance to required the claims list as non empty.