如何在Haskell中列出所有sum类型的值

14ifxucb  于 7个月前  发布在  其他
关注(0)|答案(3)|浏览(73)

问:
我想从Haskell中的类型生成一个HTML表单。

Color = Green | Yellow | Red | ....

Fruit = Apple Color Int
      | Banana Color Int String
      | ....

字符串
用户应选择具有(“苹果”、“香蕉”)或(“绿色”、“黄色”、“红色”)选项的列表
问:
但是如何将Fruit/Color类型的ALL值转换为HTML?类似于:

[ toHtml v <-  Fruit.values() ]
-- render "Apple" to html
-- render "Banana" to html


预期:

<dropdown> : values :apple/banana...
<dropdown> : values of green/yellow...
<input text> : for Int
<input text> : for String(if Banana was selected

m4pnthwp

m4pnthwp1#

Data类在这里有帮助,例如

data Color = Green | Yellow | Red deriving Data

colorStrings :: [String]
colorStrings = map show $ dataTypeConstrs (dataTypeOf Green :: DataType)

字符串
要获得Fruit,其中数据构造函数也有字段,您必须更加努力,但所需的信息应该在DataType数据类型中可用。

3z6pesqy

3z6pesqy2#

不如这样吧:

import Data.Char (toLower)

data Color = Green
           | Yellow
           | Red
             deriving (Show, Eq, Ord, Bounded, Enum)

data Fruit = Apple
           | Banana 
             deriving (Show, Eq, Ord, Bounded, Enum)

type Html = String

type Choice = (Fruit,Color)

listOfFruits :: [Choice]
listOfFruits = [(fruit, color) | fruit <- [Apple ..],
                                 color <- [Green ..]]

toDropDown :: [Choice] -> Html
toDropDown choices =
  "<label for=\"fruit_choices\">Choose a fruit:</label>\n"
  ++ "    <select name=\"fruit-choices\" id=\"fruit-choices\">\n"
  ++ toOptionList choices
  ++ "    </select>"

toOptionList :: [Choice] -> Html
toOptionList choices = concatMap toOptionHtml choices

toOptionHtml :: Choice -> Html
toOptionHtml choice =
      "        <option value=\"" ++ tagValue choice ++ "\">"
                                 ++ listText choice
                                 ++ "</option>\n"
  where tagValue (fruit,color) = map toLower (show fruit) ++ "/" ++
                                 map toLower (show color)           -- "apple/red"
        listText (fruit,color) = show color ++ " " ++ show fruit    -- "Red Apple"

字符串
这将产生输出:

*Main> putStrLn (toDropDown listOfFruits)
<label for="fruit_choices">Choose a fruit:</label>
    <select name="fruit-choices" id="fruit-choices">
        <option value="apple/green">Green Apple</option>
        <option value="apple/yellow">Yellow Apple</option>
        <option value="apple/red">Red Apple</option>
        <option value="banana/green">Green Banana</option>
        <option value="banana/yellow">Yellow Banana</option>
        <option value="banana/red">Red Banana</option>
    </select>


我的html rust 得很厉害,希望这很近。
更近了?
从Haskell的Angular 来看,棘手的部分是使用列表解析和[Green ..]fromEnum语法糖来获得FruitColor的组合。要使用范围语法,FruitColor必须是EnumBounded。这些类型类很容易派生。
我省略了IntString元素,因为我仍然不理解这部分问题。

5kgi1eie

5kgi1eie3#

我必须做几个假设来回答这个问题。起初我以为你在寻找Fruit的所有可能值,但显然这是不实际的,因为有无限多的IntString的组合。我还假设你不是试图自动生成菜单,因为你没有提到获取IntString的值。所以我假设用户正在生成一个水果记录列表,可能是一个农产品部分的库存。所以当你开始显示库存时,你已经创建了一个值列表。
在这里,我创建了一个简短的值列表,并实现了一个列表转换,将它们转换为Html字符串。

data Color = Green
           | Yellow
           | Red
             deriving Show
    
data Fruit = Apple Color Int
           | Banana Color Int String
             deriving Show

type Html = String

values :: [Fruit]
values = [Apple Red 5, Apple Green 4, Apple Yellow 3,
         Banana Green 3 "Plantain", Banana Green 2 "Regular",
         Banana Yellow 23 "Regular", Banana Red 6 "Fancy"]

toHtml :: Fruit -> Html
toHtml (Apple color number) =
       "<fruit=Apple" ++ ", color=" ++ show color ++
       ", number=" ++ show number ++ ">"
toHtml (Banana color number label) =
       "<fruit=Banana" ++ ", color=" ++ show color ++
       ", number=" ++ show number ++ ", label=" ++ label ++ ">"

showAll = [toHtml v | v <- values]

字符串
我希望这能回答你的问题。

相关问题