控制器助手模块访问user字段报错,如何写正确类型签名?
报错原因
当函数放在单个控制器文件中时,编译器可借助当前控制器的上下文自动推断CurrentUserRecord的具体结构,明确subscriptionId字段的完整类型,因此可以正常编译。当函数移动到全局的Application.Helper.Controller模块后,编译器缺失足够的上下文信息,无法确定get #subscriptionId返回的Maybe容器中承载的具体类型,进而抛出类型变量歧义的报错。
解决方法
你需要在类型签名中明确添加HasField约束,指定CurrentUserRecord的subscriptionId字段类型即可,示例如下(请将Id Subscription替换为你项目中subscriptionId字段对应的实际类型):
ensureIsSubscribed :: (HasField "subscriptionId" CurrentUserRecord (Maybe (Id Subscription))) => IO () ensureIsSubscribed = do case currentUserOrNothing of Just loggedInUser -> do case (get #subscriptionId loggedInUser) of Nothing -> redirectToPath "/NewCheckoutSession" _ -> redirectToPath "/Welcome" Nothing -> pure ()
如果你不想修改类型签名,也可以直接在取值的位置添加类型标注,让编译器获取足够的类型信息:
case (get #subscriptionId loggedInUser :: Maybe (Id Subscription)) of
内容的提问来源于stack exchange,提问作者stephenbenedict
相关产品推荐
相关产品推荐

