Mam dane dotyczące działania, które wyglądają:

type IHasShow =
  abstract member show:bool
type ShowHideNotCompletedData       = {show:bool}
type ShowHideCompletedData          = {show:bool}
[<Pojo>]
type ActionData =
  | ShowHideNotCompleted of ShowHideNotCompletedData
  | ShowHideCompleted of ShowHideCompletedData

Później próbuję przekazać showhidenotCeteddata lub pokaż Ukryj ukończone dane do funkcji, funkcja troszczy się tylko o członka boolean "Pokaż", ale nie mogę dowiedzieć się, jak przejść / rzucić:

let setShowItem (data:IHasShow) negate item =
  if data.show && (negate item.completed) then
    { item with show = true}
  else if (negate item.completed) then
    { item with show = false}
  else
    item

Ale jak nazwać tę funkcję?

let setShowFn = setShowItem (data :> IHasShow) not

Błąd:

Type constraint mismatch. The type 
    'ShowHideNotCompletedData'    
is not compatible with type
    'IHasShow'

Wypróbowany

let setShowFn = setShowItem data not

Błąd:

The type 'ShowHideNotCompletedData' is not compatible with the type 'IHasShow'

Czy istnieje droga do tego inny niż kopiować pasta SETSHOWITEM biorąc showhidenotdeddata i showhidecompleted?

Jeśli to pomoże; Pełny kod źródłowy jest tutaj: https://github.com/amsterdamharu/iot_redux_fable

Najprostszym rozwiązaniem było nie przekazanie danych, ale tylko bool:

let setShowItem show negate item =
  if (negate item.completed) then//simplified if statement
    { item with show = show}
  else
    item
//...

| ShowHideCompleted data ->
  let setShowFn = setShowItem data.show id
  { state with
      showCompleted = data.show
      items = state.items
      |> Array.map setShowFn}

Nadal zastanawiam się, jak zdefiniować rodzaj ogólny i przekazać to.

f#
4
HMR 16 luty 2017, 16:52

2 odpowiedzi

Najlepsza odpowiedź

W obecnym rozwiązaniu, dwa typy ShowHideNotCompletedData i ShowHideCompletedData są rekordami. Mają wszystkie pola interfejsu, ale nie wystąpią ich wyraźnie. Rozwiązaniem jest wyjaśnienie interfejsu:

type ShowHideNotCompletedData(show) =
    interface IHasShow with
        member this.show = show
type ShowHideCompletedData(show) = 
    interface IHasShow with
        member this.show = show

Instancja jako ShowHideNotCompletedData true. W przypadku rozwiązań alternatywnych można skonsultować się z niektórymi pytaniami o wpisanie kaczki, na przykład to.

Powiedziałem wszystko: mam przeczucie, że definicja typu danych jest trochę skomplikowana. @Robkuz opublikował odpowiedź, która robi bez interfejsu. Twoja własna sugestia po prostu przekazuje Bool do funkcji wydaje się jeszcze lepsze pod względem modułowości i testów.

3
Community 23 maj 2017, 12:25

Muszę przyznać: nie lubię interfejsów w F # - nie w ogóle, ale myślę, że są składniowe są łącznym opuszczeniem. Więc częściej nie używam funkcji inline z ograniczeniami typu.
Achtung: Korzystanie z tego rodzaju kodu prawdopodobnie zabije kilkanaście szczeniąt lub sortowania

Pierwsza rzecz pozbywa się twojego interfejsu i wdrożenie tego (co w każdym razie zapomniałeś ;-))

type ShowHideNotCompletedData       = {show:bool}
type ShowHideCompletedData          = {show:bool}
type ActionData =
    | ShowHideNotCompleted of ShowHideNotCompletedData
    | ShowHideCompleted of ShowHideCompletedData

Następnie napisz to naprawdę szaloną funkcję

let inline show< ^T when ^T : (member show : bool)> (x:^T) = 
      (^T : (member show : bool)(x)) 

I zastosuj go

let setShowItem data =
    match data with
    | ShowHideNotCompleted x -> show x
    | ShowHideCompleted x -> show x
3
robkuz 16 luty 2017, 14:34