Я считаю, что вы можете сделать это с помощью комбинатора zoom
из Control.Lens.Zoom
:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Monad.State
data SomeState = SomeState { _int :: Int, _string :: String } deriving (Show)
makeLenses ''SomeState
updateInt :: Int -> State Int ()
updateInt x = id .= x
updateString :: String -> State String ()
updateString x = id .= x
updateSomeState :: Int -> State SomeState ()
updateSomeState x = zoom int (updateInt x)
GHCi:
*Main> runStateT (updateSomeState 5) (SomeState 3 "hi")
Identity ((),SomeState {_int = 5, _string = "hi"})
Используйте lapply()
или sapply()
, потому что ваш объект - это список. Я думаю, что вы могли бы проверить разницу между length()
и lengths()
. Они оба существуют, но имеют разные способности. Я предоставляю два решения foo1
и foo2
:
foo1 <- function(...){
L <- list(...)
sapply(L, function(x) length(unique(x)))
}
foo2 <- function(...){
L <- list(...)
lengths(lapply(L, unique))
}
a = rep(c("a", "b"), 30) # Vector `a`
b = rep(c("a", "b"), 20) # Vector `b`
foo1(a, b)
# [1] 2 2
foo2(a, b)
# [1] 2 2
Вот ответ
Вы использовали функцию unlist - поэтому вы вернулись к началу с длинами векторов!
используйте этот код вместо
foo <- function(a,b){
L <- list(a,b)
lengths(unique(L)) ### this return 1 1
}
a = rep(c("a", "b"), 30) # Vector `a`
b = rep(c("a", "b"), 20) # Vector `b`
foo(a, b)