这对于this question来说是理想的,除了elm从那以后发生了变化,所以答案不再有效(特别是不再有Decode.customDecoder
个对象。)
你如何在elm-core>中做同样的事情5.0.0?
答案 0 :(得分:6)
一种方法(从Elm 0.18和核心5.0开始)将是这样的:
df <- read.table(text='product share_per return_per min_share_per
prod1 0.5 0.1 0.2
prod2 0.2 0.4 0.1
prod3 0.2 0.05 0.0
prod4 0.1 0.04 0.0
prod5 0.0 0.3 0.0', header=TRUE)
ret <- df$return_per
fn <- function(sp) sum(ret*sp) # objective
Amat <- rbind(diag(nrow(df)), diag(-1,nrow(df)), rep(-1,nrow(df))) # constraints
bvec <- c(df$min_share_per, rep(-1, nrow(df)), -1) # sp_j >= min_share_per,
# sp_j <= 1 and
# sum_j sp_j <= 1
init <- c(0.5,0.2,0.2,0.05,0.01) # making sure that the initial value is in the feasible region
sol <- constrOptim(init, fn, NULL, ui = Amat, ci = bvec, control=list(fnscale=-1)) # maximize
round(sol$par, 2)
# [1] 0.2 0.8 0.0 0.0 0.0
标准库中的stringIntDecoder : Decoder Int
stringIntDecoder =
Json.Decode.map (\str -> String.toInt (str) |> Result.withDefault 0) Json.Decode.string
函数接受一个字符串并尝试将其转换为整数,并返回一个Result。 String.toInt
执行其名称所暗示的内容 - 您为其提供了一些默认值和结果,如果结果为Result.withDefault
,则会得到Ok x
但如果它是x
则会得到你提供的默认值,这里是0.如果你愿意,可以自己编写一个函数来自己处理一个Result,而不是传递那个函数。
答案 1 :(得分:3)
您可以使用succeed
中的fail
和Json.Decode
创建自己的自定义解码器。我改变了下面的参数顺序,使其可以链接。
修改:从结果问题中分离出解码器问题。
import Json.Decode as Json
import Result
-- // This is a Result helper function that could be used elsewhere.
-- // Currently, there is no Result.either in Elm core.
eitherR : (x -> b) -> (a -> b) -> Result x a -> b
eitherR fErr fOk result =
case result of
Err x ->
fErr x
Ok a ->
fOk a
customDecoder : (a -> Result String b) -> Json.Decoder a -> Json.Decoder b
customDecoder fResult decoder =
decoder |> Json.andThen (fResult >> eitherR Json.fail Json.succeed)
将此问题插入相关问题......
let number =
Json.oneOf [ Json.int, Json.string |> customDecoder String.toInt ]
这是另一个使用示例。这是onChange
的版本,它将值转换为整数。当您知道选项值是Int。
select
主要有用
import Html
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import String
onChangeInt : (Int -> msg) -> Attribute msg
onChangeInt fMsg =
on "change" (targetValue |> customDecoder String.toInt |> Json.map fMsg)
请注意,targetValue
在Html.Events模块中定义:
targetValue : Decoder String
答案 2 :(得分:1)
decodeString parseInt """ "123" """
查看有关自定义解码器的tutorial,例如日期。重用fromResult
方法。
了解parseInt
函数中使用的function composition (<<)。
答案 3 :(得分:0)
鉴于在对另一个答案的评论中,你表明需要接受可能的失败,你可以使用一个Maybe。
stringIntDecoder : Decoder (Maybe Int)
stringIntDecoder =
Json.Decode.map (String.toInt >> Result.toMaybe) Json.Decode.string
或者
stringIntDecoder : Decoder (Result String Int)
stringIntDecoder =
Json.Decode.map (String.toInt) Json.Decode.string
答案 4 :(得分:0)
对于使用targetValue文档的Elm 0.19,代码变为:
import Html.Events
import Json.Decode
onIntInput : (Int -> msg) -> Attribute msg
onIntInput tagger =
Html.Events.stopPropagationOn "input" <|
Json.Decode.map alwaysStop (Json.Decode.map tagger targetIntValue)
targetIntValue : Decoder Int
targetIntValue =
Json.Decode.at ["target", "value"] Json.Decode.string |> Json.Decode.andThen (\value ->
case String.toInt value of
Just number -> Json.Decode.succeed number
Nothing -> Json.Decode.fail "not a number")
alwaysStop : a -> (a, Bool)
alwaysStop x =
(x, True)
,然后可以在使用onInput的地方使用onIntInput。
答案 5 :(得分:0)
这是一种避免选择粗略默认值的解决方案:
import Json.Decode as Decode exposing (Decoder)
decodeIntString : Decoder (Maybe Int)
decodeIntString =
Decode.map String.toInt Decode.string
decodeMaybeFail : Maybe a -> Decoder a
decodeMaybeFail val =
case val of
Just a ->
Decode.succeed a
Nothing ->
Decode.fail "'Nothing' value can't be decoded"
然后将其与
一起使用Decode.andThen decodeMaybeFail decodeIntString
(类型为Decoder Int
,因此您可以像使用Decode.int
一样使用它)
乍一看并不明显,但它说明了如何将此问题分解为简单的小步骤。
我认为函数decodeMaybeFail : Maybe a -> Decoder a
应该在标准Json.Decode
模块中。