diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
 # Revision history for futhark-data
 
+## 1.0.3.0 -- 2021-12-06
+
+* The `GetValue [t]` instance no longer produces an empty list on any
+  non-array type.
+
+* New typeclass `PutValue1` as a version of `PutValue` that cannot
+  fail.
+
 ## 1.0.2.0 -- 2021-08-12
 
 * Support underscores in numeric literals.
diff --git a/futhark-data.cabal b/futhark-data.cabal
--- a/futhark-data.cabal
+++ b/futhark-data.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               futhark-data
-version:            1.0.2.0
+version:            1.0.3.0
 synopsis:           An implementation of the Futhark data format.
 
 description: The Futhark compiler and its tools uses a simple external
diff --git a/src/Futhark/Data.hs b/src/Futhark/Data.hs
--- a/src/Futhark/Data.hs
+++ b/src/Futhark/Data.hs
@@ -23,6 +23,7 @@
     -- * Converting values
     GetValue (..),
     PutValue (..),
+    PutValue1 (..),
     valueElems,
   )
 where
@@ -338,7 +339,9 @@
   getValue :: Value -> Maybe t
 
 instance GetValue t => GetValue [t] where
-  getValue = mapM getValue . valueElems
+  getValue v
+    | null $ valueShape v = Nothing
+    | otherwise = mapM getValue $ valueElems v
 
 instance GetValue Bool where
   getValue (BoolValue shape vs)
@@ -401,28 +404,28 @@
   putValue :: t -> Maybe Value
 
 instance PutValue Int8 where
-  putValue = Just . I8Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Int16 where
-  putValue = Just . I16Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Int32 where
-  putValue = Just . I32Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Int64 where
-  putValue = Just . I64Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Word8 where
-  putValue = Just . U8Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Word16 where
-  putValue = Just . U16Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Word32 where
-  putValue = Just . U32Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue Word64 where
-  putValue = Just . U64Value mempty . SVec.singleton
+  putValue = Just . putValue1
 
 instance PutValue [Value] where
   putValue [] = Nothing
@@ -464,3 +467,32 @@
     Just $ U8Value size $ byteStringToVector bs
     where
       size = SVec.fromList [fromIntegral (BS.length bs)]
+
+-- | Like 'PutValue', but only for scalars - which means it cannot
+-- fail.
+class PutValue1 t where
+  putValue1 :: t -> Value
+
+instance PutValue1 Int8 where
+  putValue1 = I8Value mempty . SVec.singleton
+
+instance PutValue1 Int16 where
+  putValue1 = I16Value mempty . SVec.singleton
+
+instance PutValue1 Int32 where
+  putValue1 = I32Value mempty . SVec.singleton
+
+instance PutValue1 Int64 where
+  putValue1 = I64Value mempty . SVec.singleton
+
+instance PutValue1 Word8 where
+  putValue1 = U8Value mempty . SVec.singleton
+
+instance PutValue1 Word16 where
+  putValue1 = U16Value mempty . SVec.singleton
+
+instance PutValue1 Word32 where
+  putValue1 = U32Value mempty . SVec.singleton
+
+instance PutValue1 Word64 where
+  putValue1 = U64Value mempty . SVec.singleton
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -5,8 +5,10 @@
 import Control.Monad
 import Data.Binary (encode)
 import qualified Data.ByteString.Lazy.Char8 as LBS
+import Data.Int
 import qualified Data.Text as T
 import qualified Data.Vector.Storable as SVec
+import Data.Word
 import Futhark.Data
 import Futhark.Data.Compare
 import Futhark.Data.Parser
@@ -140,9 +142,23 @@
           (TestValue <$> runParser (parseValue space <* eof) "" s)
           @?= Nothing
 
+getValueTests :: TestTree
+getValueTests =
+  testGroup
+    "GetValue"
+    [ test (putValue1 (1 :: Int32)) (Nothing :: Maybe [Word8]),
+      test (putValue1 (1 :: Int32)) (Just (1 :: Int32))
+    ]
+  where
+    test v expected =
+      testCase (unwords ["getValue", v', "==", show expected]) $
+        getValue v @?= expected
+      where
+        v' = T.unpack (valueText v)
+
 allTests :: TestTree
 allTests =
-  testGroup "" [readerTests, parserTests]
+  testGroup "" [readerTests, parserTests, getValueTests]
 
 main :: IO ()
 main = defaultMain allTests
