diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,7 @@
+# Changelog for single-tuple
+
+## 0.1.0.0
+
+2019.10.10
+
+Release.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2019 Kazuki Okamoto
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# homotuple
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/single-tuple.cabal b/single-tuple.cabal
new file mode 100644
--- /dev/null
+++ b/single-tuple.cabal
@@ -0,0 +1,59 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.1.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 4ba9f1d2514aef5df15c28c62a56b699783522afb6aec15cf63d24c6dd60ab5e
+
+name:           single-tuple
+version:        0.1.0.0
+synopsis:       a class for single tuple implementations
+description:    a class for single tuple implementations
+category:       Data
+homepage:       https://github.com/kakkun61/tuple#readme
+bug-reports:    https://github.com/kakkun61/tuple/issues
+author:         Kazuki Okamoto
+maintainer:     kazuki.okamoto@kakkun61.com
+copyright:      2019 Kazuki Okamoto
+license:        Apache
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+  type: git
+  location: https://github.com/kakkun61/tuple
+
+library
+  exposed-modules:
+      Data.Tuple.Single
+  other-modules:
+      Paths_single_tuple
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -Wcompat -Wincomplete-uni-patterns -Wincomplete-record-updates -Wmonomorphism-restriction -Wmissing-exported-signatures -Wmissing-export-lists -Wmissing-home-modules -Wmissing-import-lists -Widentities -Wredundant-constraints -Wpartial-fields -Wno-name-shadowing -Wno-unticked-promoted-constructors
+  build-depends:
+      OneTuple >=0.2 && <0.3
+    , Only >=0.1 && <0.2
+    , base >=4.12 && <4.13
+  default-language: Haskell2010
+
+test-suite test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Data.Tuple.SingleSpec
+      Paths_single_tuple
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -Wcompat -Wincomplete-uni-patterns -Wincomplete-record-updates -Wmonomorphism-restriction -Wmissing-exported-signatures -Wmissing-export-lists -Wmissing-home-modules -Wmissing-import-lists -Widentities -Wredundant-constraints -Wpartial-fields -Wno-name-shadowing -Wno-unticked-promoted-constructors -threaded -rtsopts -with-rtsopts=-N -Wno-missing-export-lists -Wno-missing-import-lists
+  build-depends:
+      OneTuple >=0.2 && <0.3
+    , Only >=0.1 && <0.2
+    , base >=4.12 && <4.13
+    , hspec
+    , single-tuple
+  default-language: Haskell2010
diff --git a/src/Data/Tuple/Single.hs b/src/Data/Tuple/Single.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tuple/Single.hs
@@ -0,0 +1,49 @@
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE Safe            #-}
+{-# LANGUAGE ViewPatterns    #-}
+
+{-# OPTIONS_HADDOCK show-extensions #-}
+
+-- |
+-- Copyright   :  Kazuki Okamoto
+-- License     :  see LICENSE
+-- Maintainer  :  kazuki.okamoto@kakkun61.com
+-- Stability   :  experimental
+-- Portability :  GHC
+--
+-- A class for 1-tuples.
+
+module Data.Tuple.Single
+  ( Single (..)
+  , pattern Single
+  ) where
+
+import Data.Functor.Identity (Identity (Identity, runIdentity))
+import Data.Tuple.OneTuple   (OneTuple (OneTuple), only)
+import Data.Tuple.Only       (Only (Only, fromOnly))
+
+class Single t where
+  wrap :: a -> t a
+  unwrap :: t a -> a
+
+pattern Single :: Single t => a -> t a
+pattern Single a <- (unwrap -> a) where
+  Single a = wrap a
+
+instance Single Identity where
+  wrap = Identity
+  unwrap = runIdentity
+
+{-# COMPLETE Single :: Identity #-}
+
+instance Single Only where
+  wrap = Only
+  unwrap = fromOnly
+
+{-# COMPLETE Single :: Only #-}
+
+instance Single OneTuple where
+  wrap = OneTuple
+  unwrap = only
+
+{-# COMPLETE Single :: OneTuple #-}
diff --git a/test/Data/Tuple/SingleSpec.hs b/test/Data/Tuple/SingleSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/Tuple/SingleSpec.hs
@@ -0,0 +1,47 @@
+module Data.Tuple.SingleSpec (spec) where
+
+import Data.Tuple.Single
+
+import Test.Hspec
+
+import Data.Functor.Identity
+import Data.Tuple.OneTuple
+import Data.Tuple.Only
+
+spec :: Spec
+spec = do
+  describe "Identity" $ do
+    it "unwrap . wrap" $ do
+      unwrap (wrap () :: Identity ()) `shouldBe` ()
+
+    it "wrap . unwrap" $ do
+      let a = Identity ()
+      wrap (unwrap a) `shouldBe` a
+
+    it "pattern destruct construct" $ do
+      let Single a = Single () :: Identity ()
+      a `shouldBe` ()
+
+  describe "Only" $ do
+    it "unwrap . wrap" $ do
+      unwrap (wrap () :: Only ()) `shouldBe` ()
+
+    it "wrap . unwrap" $ do
+      let a = Only ()
+      wrap (unwrap a) `shouldBe` a
+
+    it "pattern destruct construct" $ do
+      let Single a = Single () :: Only ()
+      a `shouldBe` ()
+
+  describe "OneTuple" $ do
+    it "unwrap . wrap" $ do
+      unwrap (wrap () :: OneTuple ()) `shouldBe` ()
+
+    it "wrap . unwrap" $ do
+      let a = OneTuple ()
+      wrap (unwrap a) `shouldBe` a
+
+    it "pattern destruct construct" $ do
+      let Single a = Single () :: OneTuple ()
+      a `shouldBe` ()
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
