我有以下类型用户:
type alias User =
{ id : Int
, name : String
, age : Maybe Int
, deleted : Bool
}
用户是我的模型中使用的类型:
type alias Model =
{ users : List User
, name : String
, age : String
, message : String
}
当我使用像这样的List.map迭代“List User”时......
Delete id ->
let
newUserList =
List.map
(\user ->
if user.id == id then
{ user | deleted = True }
else
user
)
model.users
in
( { model | users = newUserList }, Cmd.none )
......编译告诉我:
The 2nd argument to function `map` is causing a mismatch.
List.map
(\user ->
if user.id == id then
{ user | deleted = True }
else
user
)
model.users
Function `map` is expecting the 2nd argument to be:
List { a | id : Int, name : String }
But it is:
List (Bool -> User)
对我来说这很奇怪。 为什么我的地图功能会更改类型用户...? 我不改变它,我只是迭代,映射每个用户,如果我找到了正确的,通过它的id,我将删除的值更改为True ...
我有点困惑...... 有人可以帮忙吗?
亲切的问候:)
更新:我似乎不是List.map函数的问题,而是类别别名User声明的问题。 一旦我添加另一个值,这就会破坏......
以下是它的完整代码。它保持非常简单。 注意:只要取消注释Users属性“已删除”,编译器就会抛出错误
module Main exposing (..)
import Html exposing (Html, text, h1, div, img, input, form, ul, li, i, hr, br)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.App as App
import String
import Random
--import Debug
--import Uuid
main : Program Never
main =
App.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
--MODEL
type alias Model =
{ users : List User
, name : String
, age : String
, message : String
}
type alias User =
{ id : Int
, name : String
, age :
Maybe Int
-- , deleted : Bool
}
init : ( Model, Cmd Msg )
init =
( initModel, Cmd.none )
initModel : Model
initModel =
{ users = []
, name = ""
, age = ""
, message = ""
}
--UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
InsertName username ->
( { model | name = username }, Cmd.none )
InsertAge age ->
let
newAge =
case String.toInt age of
Err err ->
""
Ok value ->
toString value
newMessage =
case String.toInt age of
Err err ->
"Age must be a number!"
Ok int ->
""
in
( { model | age = newAge, message = newMessage }, Cmd.none )
InitNewUser ->
( model, Random.generate AddNewUser (Random.int 1 9999) )
AddNewUser randomId ->
if String.isEmpty model.name then
( { model | message = "Please give a name" }, Cmd.none )
else
let
ageAsInt =
case String.toInt model.age of
Err err ->
Nothing
Ok int ->
Just int
newUser =
User randomId model.name ageAsInt
newUserList =
newUser :: model.users
in
( { model | users = newUserList, name = "", age = "" }, Cmd.none )
Delete id ->
let
newUserList =
List.map
(\user ->
if user.id == id then
{ user | name = "--deleted--" }
else
user
)
model.users
in
( { model | users = newUserList }, Cmd.none )
--VIEW
type Msg
= InsertName String
| InsertAge String
| AddNewUser Int
| InitNewUser
| Delete Int
userListView : Model -> Html Msg
userListView model =
let
newList =
List.filter (\user -> (user.name /= "--deleted--")) model.users
in
newList
|> List.sortBy .name
|> List.map userView
|> ul []
userView : User -> Html Msg
userView user =
let
ageAsString =
case user.age of
Just val ->
val |> toString
Nothing ->
"-"
in
li []
[ div [] [ text ("ID: " ++ toString user.id) ]
, div [] [ text ("Name: " ++ user.name) ]
, div [] [ text ("Age: " ++ ageAsString) ]
, input [ type' "button", value "Delete", onClick (Delete user.id) ] []
]
view : Model -> Html Msg
view model =
div [ class "wrapper" ]
[ h1 [] [ text ("We have " ++ toString (List.length model.users) ++ " Users") ]
, Html.form []
[ input [ type' "text", onInput InsertName, placeholder "Name", value model.name ] []
, input [ type' "text", onInput InsertAge, placeholder "Age", value model.age ] []
, input [ type' "button", onClick InitNewUser, value "Add new user" ] []
]
, div [] [ text model.message ]
, userListView model
, hr [] []
, div [] [ text (toString model) ]
]
答案 0 :(得分:1)
问题是AddNewUser
消息的这一部分:
newUser =
User randomId model.name ageAsInt
当您使用False
属性时,它缺少deleted
作为第四个参数。
如果您不包含它,User
函数将返回部分应用的函数,该函数仍然需要Bool
才能返回正确的用户。即使所有类型和函数都有适当的注释,编译器似乎也会被抛弃。
导致更好的错误消息的另一种方法是定义newUser
,如下所示:
newUser =
{ id = randomId
, name = model.name
, age = ageAsInt
, deleted = False
}