是否有更优雅的写作方式:(下面的代码编译)
getModelSorterOpt sortOrder sortField = do
case sortOrder of
"Asc" ->
case sortField of
"id" -> Just $ Asc ModelId
"name" -> Just $ Asc ModelName
"created" -> Just $ Asc ModelCreated
_ -> Nothing
"Desc" ->
case sortField of
"id" -> Just $ Desc ModelId
"name" -> Just $ Desc ModelName
"created" -> Just $ Desc ModelCreated
_ -> Nothing
主要问题是我不能使用变量而不是“Asc / Desc”情况。像下面的代码一样,未能进行类型检查。
getModelSorterOpt sortOrder sortField =
case sortField of
"id" -> Just $ sortOrder' ModelId
"name" -> Just $ sortOrder' ModelName
"created" -> Just $ sortOrder' ModelCreated
_ -> Nothing
where sortOrder' = case sortOrder of
"Asc" -> Asc
"Desc" -> Desc
GHC表示,它不希望ModelId和ModelName成为同一案例的一部分,因为它们是不同的类型。我认为这是有效的。但是,Asc ModelId
与Asc ModelName
的类型相同。我如何告诉GHC?
哈马尔的初步答案有效。此版本仍无效:
getModelSorterOpt sortOrder sortField = do
(sortOrder'' :: EntityField Model a -> SelectOpt Model ) <- sortOrder'
case sortField of
"id" -> Just $ sortOrder'' ModelId
"name" -> Just $ sortOrder'' ModelName
"created" -> Just $ sortOrder'' ModelCreated
_ -> Nothing
where sortOrder' = case sortOrder of
"Asc" -> Just Asc
"Desc" -> Just Desc
_ -> Nothing
我得到的错误是ModelId
和ModelName
属于不同类型。这是因为sortOrder''
是单独使用的吗?
答案 0 :(得分:1)
我通过将查找键放在关联列表中来修改您的设计。将数据移动到数据结构而不是控制结构似乎是一种胜利。我也对你的类型(或与它们类似的类型)做了一些假设。根据您是否喜欢/ grok Applicatives:
,这里有两个选项module Sorting where
import Control.Applicative ((<*>))
data Field = ModelId | ModelName | ModelCreated
data Sorting = Asc Field | Desc Field
orderMap :: [(String, Field -> Sorting)]
orderMap =
[ ("Asc", Asc)
, ("Desc", Desc)
]
fieldMap :: [(String, Field)]
fieldMap =
[ ("id", ModelId)
, ("name", ModelName)
, ("created", ModelCreated)
]
lookupSorting :: String -> String -> Maybe Sorting
lookupSorting orderName fieldName = do
order <- lookup orderName orderMap
field <- lookup fieldName fieldMap
return (order field)
lookupSorting' :: String -> String -> Maybe Sorting
lookupSorting' orderName fieldName =
lookup orderName orderMap <*> lookup fieldName fieldMap
答案 1 :(得分:1)
尝试为sortOrder'
提供类型签名。
where sortOrder' :: EntityField Model typ -> SelectOpt Model
sortOrder' = case sortOrder of
"Asc" -> Asc
"Desc" -> Desc
This compiles使用GHC 7.6.2。