如何在记录中设置默认值

时间:2015-08-12 12:46:19

标签: haskell record

我正在尝试在可以覆盖的记录对象中设置默认值。

data Car c y = Car {
    company :: c,
    year :: y
    }

我想做的是设置默认值:

data Car c y = Car {
    company :: c -- OR "Ford"
    year :: y
    }

到目前为止,我已尝试将c的类型设置为Maybe类型:

data Car = Car {
    company:: Maybe String
    year :: Maybe Int
    }

但是我得到了这个可预测的错误:

Fields of `Car' not initialised: year
具有讽刺意味的是,这正是我想要解决的问题。我想生成一个新记录,其中包含我未设置的值已经初始化。我发现的一种方法是部分应用Car类型:

data Car c y = {
    company :: c,
    year :: y
    }

let ford = Car "Ford" 

-- This produces a function (y -> Car [Char] y)

然而,这产生了两个新问题:

  1. 如果我的数据类型有100多个字段类型,我最终会得到100个因子curried函数

  2. 我可以创建的部分应用函数取决于声明中变量的顺序。你会注意到我不能产生car1988函数,例如。

  3. 如何编写一个允许我使用默认值创建记录的函数?请帮忙。

2 个答案:

答案 0 :(得分:15)

这就是Haskell prefers to handle in a library的问题,而不是破解一些硬连线语言支持(这可能会导致各种问题,就像在C ++中一样)。

import Data.Default

instance Default Car where
  def = Car Nothing Nothing
          -- or whatever you want as the defaults

ford :: Car
ford = def { company = Just "Ford" }
  

GHCI>福特
  Car {company = Just“Ford”,year = Nothing}

您可以只定义Default

,而不是使用defaultCar

您可能需要使用cabal来安装data-default,如果它尚未安装在您的系统中。

答案 1 :(得分:0)

在使用Data.Text时,我会使用稍微冗长的方法。

{-#Language OverloadedString#-}

import Data.Text as T

data Car c y = Car {
    company :: Text 
    year :: Double
    }

toCar :: [T.Text] -> Car
toCar inp = case inp of 
              [] -> fail "Give me an input"
              [v:h] -> Car { company = justifyRight 1 "Ford" h 
                           , year = read $ T.unpack $ last inp
                           }

这将接受诸如inp ["8"]inp ["Ashburn", "8"]的输入